feat(plc4go/bacnetip): improvements:

- inheritance support improved
- bugfixes
- write tag data
- split up debugging
- more logging
- inital objects
diff --git a/plc4go/internal/bacnetip/ApplicationLayerMessageCodec.go b/plc4go/internal/bacnetip/ApplicationLayerMessageCodec.go
index 522cd47..c6107e2 100644
--- a/plc4go/internal/bacnetip/ApplicationLayerMessageCodec.go
+++ b/plc4go/internal/bacnetip/ApplicationLayerMessageCodec.go
@@ -73,9 +73,9 @@
 	}
 	// TODO: workaround for strange address parsing
 	address.AddrTuple = pdu.NewAddressTuple(fmt.Sprintf("%d.%d.%d.%d", address.AddrAddress[0], address.AddrAddress[1], address.AddrAddress[2], address.AddrAddress[3]), *address.AddrPort)
-	application, err := app.NewBIPSimpleApplication(localLog, &device.LocalDeviceObject{
-		NumberOfAPDURetries: func() *uint { retries := uint(10); return &retries }(),
-	}, *address, &a.deviceInfoCache, nil)
+	application, err := app.NewBIPSimpleApplication(localLog, device.NewLocalDeviceObject(comp.NoArgs,
+		comp.NewKWArgs(comp.KWNumberOfAPDURetries, func() *uint { retries := uint(10); return &retries }()),
+	), *address, &a.deviceInfoCache, nil)
 	if err != nil {
 		return nil, err
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCI.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCI.go
index 50bc8c8..348bec8 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCI.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCI.go
@@ -88,52 +88,58 @@
 
 	// Deprecated: hacky workaround
 	bytesToDiscard int
+
+	_leafName string
 }
 
 var _ APCI = (*_APCI)(nil)
 
-func NewAPCI(args Args, kwArgs KWArgs) APCI {
+func NewAPCI(args Args, kwArgs KWArgs, options ...Option) (APCI, error) {
+	return newAPCI(args, kwArgs, options...)
+}
+
+func newAPCI(args Args, kwArgs KWArgs, options ...Option) (*_APCI, error) {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
-	a := &_APCI{}
+	a := &_APCI{
+		_leafName: ExtractLeafName(options, "APCI"),
+	}
+	options = AddLeafTypeIfAbundant(options, a)
 	a.DebugContents = NewDebugContents(a, "apduType", "apduSeg", "apduMor", "apduSA", "apduSrv",
 		"apduNak", "apduSeq", "apduWin", "apduMaxSegs", "apduMaxResp",
 		"apduService", "apduInvokeID", "apduAbortRejectReason")
-	a.PCI = NewPCI(args, kwArgs)
+	a.PCI = NewPCI(args, kwArgs, options...)
 	a.AddExtraPrinters(a.PCI.(DebugContentPrinter))
-	return a
+	return a, nil
 }
 
 func (a *_APCI) GetDebugAttr(attr string) any {
 	switch attr {
 	case "apduType":
-		return a.apduType
+		if a.apduType != nil {
+			return *a.apduType
+		}
 	case "apduSeg":
-		if !a.apduSeg {
-			return nil
+		if a.apduSeg {
+			return a.apduSeq
 		}
-		return a.apduSeq
 	case "apduMor":
-		if !a.apduMor {
-			return nil
+		if a.apduMor {
+			return a.apduMor
 		}
-		return a.apduMor
 	case "apduSA":
-		if !a.apduSA {
-			return nil
+		if a.apduSA {
+			return a.apduSA
 		}
-		return a.apduSA
 	case "apduSrv":
-		if !a.apduSrv {
-			return nil
+		if a.apduSrv {
+			return a.apduSrv
 		}
-		return a.apduSrv
 	case "apduNak":
-		if !a.apduNak {
-			return nil
+		if a.apduNak {
+			return a.apduNak
 		}
-		return a.apduNak
 	case "apduSeq":
 		if a.apduSeq != nil {
 			return *a.apduSeq
@@ -504,7 +510,7 @@
 }
 
 func (a *_APCI) String() string {
-	sname := StructName()
+	sname := a._leafName
 
 	// expand the type if possible
 	stype := ""
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCISequence.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCISequence.go
index b531734..d530ab1 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCISequence.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APCISequence.go
@@ -49,32 +49,36 @@
 	tagList *TagList
 }
 
-func NewAPCISequence(args Args, kwArgs KWArgs, opts ...func(*APCISequence)) (*APCISequence, error) {
+func NewAPCISequence(args Args, kwArgs KWArgs, options ...Option) (*APCISequence, error) {
 	a := &APCISequence{}
-	for _, opt := range opts {
-		opt(a)
+	ApplyAppliers(options, a)
+	if _debug != nil {
+		_debug("__init__ %r %r", args, kwArgs)
 	}
 	if a._contract == nil {
 		a._contract = a
 	} else {
 		a._contract.(APCISequenceContractRequirement).SetAPCISequence(a)
 	}
-	a._APCI = NewAPCI(args, kwArgs).(*_APCI)
+	options = AddLeafTypeIfAbundant(options, a)
 	var err error
-	a.Sequence, err = NewSequence(args, kwArgs, WithSequenceExtension(a._contract))
+	a._APCI, err = CreateSharedSuperIfAbundant[_APCI](options, newAPCI, args, kwArgs, options...)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating APCI")
+	}
+	a.Sequence, err = NewSequence(args, kwArgs, Combine(options, WithSequenceExtension(a._contract))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating sequence")
 	}
+	a.AddExtraPrinters(a.Sequence)
 
 	// start with an empty tag list
 	a.tagList = NewTagList(nil)
 	return a, nil
 }
 
-func WithAPCISequenceExtension(contract APCISequenceContractRequirement) func(*APCISequence) {
-	return func(a *APCISequence) {
-		a._contract = contract
-	}
+func WithAPCISequenceExtension(contract APCISequenceContractRequirement) GenericApplier[*APCISequence] {
+	return WrapGenericApplier(func(a *APCISequence) { a._contract = contract })
 }
 
 func (a *APCISequence) SetSequence(sequence *Sequence) {
@@ -82,6 +86,9 @@
 }
 
 func (a *APCISequence) Encode(apdu Arg) error {
+	if _debug != nil {
+		_debug("encode %r", apdu)
+	}
 	switch apdu := apdu.(type) {
 	case Updater:
 		if err := apdu.Update(a); err != nil {
@@ -107,6 +114,9 @@
 }
 
 func (a *APCISequence) Decode(apdu Arg) error {
+	if _debug != nil {
+		_debug("decode %r", apdu)
+	}
 	// copy the header fields
 	if err := a.Update(apdu); err != nil {
 		return errors.Wrap(err, "error updating APDU")
@@ -126,8 +136,14 @@
 	if err := a.Sequence.Decode(a.tagList); err != nil {
 		return errors.Wrap(err, "error encoding TagList")
 	}
+	if _debug != nil {
+		_debug("    - tag list: %r", a.tagList)
+	}
 
 	if len(a.tagList.GetTagList()) > 0 {
+		if _debug != nil {
+			_debug("    - trailing unmatched tags")
+		}
 		return errors.New("trailing unmatched tags")
 	}
 	return nil
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APDU.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APDU.go
index b41a3f0..f9f30ba 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_APDU.go
@@ -21,8 +21,6 @@
 
 import (
 	"context"
-	"fmt"
-	"strings"
 
 	"github.com/pkg/errors"
 
@@ -34,6 +32,7 @@
 )
 
 type APDU interface {
+	Copyable
 	readWriteModel.APDU
 	APCI
 	PDUData
@@ -46,13 +45,18 @@
 
 var _ APDU = (*__APDU)(nil)
 
-func NewAPDU(args Args, kwArgs KWArgs) (APDU, error) {
+func NewAPDU(args Args, kwArgs KWArgs, options ...Option) (APDU, error) {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
 	a := &__APDU{}
-	a._APCI = NewAPCI(args, kwArgs).(*_APCI)
-	a.PDUData = NewPDUData(args, kwArgs)
+	options = AddLeafTypeIfAbundant(options, a)
+	var err error
+	a._APCI, err = CreateSharedSuperIfAbundant[_APCI](options, newAPCI, args, kwArgs, options...)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating APCI")
+	}
+	a.PDUData = NewPDUData(args, kwArgs, options...)
 	a.AddExtraPrinters(a.PDUData.(DebugContentPrinter))
 	return a, nil
 }
@@ -133,9 +137,5 @@
 }
 
 func (a *__APDU) String() string {
-	if IsDebuggingActive() {
-		pci := "\t" + strings.Join(strings.Split(a.PCI.String(), "\n"), "\n\t")
-		return fmt.Sprintf("<APDU instance at %p>\n%s\n\tpduData = x'%s'", a, pci, Btox(a.GetPduData(), "."))
-	}
-	return fmt.Sprintf("APDU{%s}", a.PCI)
+	return a._APCI.String()
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedPrivateTransferRequest.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedPrivateTransferRequest.go
index a8bd3b1..7b843a4 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedPrivateTransferRequest.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedPrivateTransferRequest.go
@@ -37,7 +37,7 @@
 	sequenceElements []Element
 }
 
-func NewConfirmedPrivateTransferRequest(args Args, kwArgs KWArgs) (*ConfirmedPrivateTransferRequest, error) {
+func NewConfirmedPrivateTransferRequest(args Args, kwArgs KWArgs, options ...Option) (*ConfirmedPrivateTransferRequest, error) {
 	c := &ConfirmedPrivateTransferRequest{
 		serviceChoice: readWriteModel.BACnetConfirmedServiceChoice_CONFIRMED_PRIVATE_TRANSFER,
 		sequenceElements: []Element{
@@ -46,16 +46,15 @@
 			NewElement("serviceParameters", Vs2E(NewAny), WithElementContext(2), WithElementOptional(true)),
 		},
 	}
-	if _, ok := kwArgs[KWCompRootMessage]; !ok {
-		kwArgs[KWCompRootMessage] = readWriteModel.NewBACnetConfirmedServiceRequestConfirmedPrivateTransfer(
-			readWriteModel.CreateBACnetVendorIdContextTagged(0, 0),     // TODO: get right values
-			readWriteModel.CreateBACnetContextTagUnsignedInteger(1, 0), // TODO: get right values
-			nil,
-			0,
-		)
-	}
+	options = AddRootMessageIfAbundant(options, readWriteModel.NewBACnetConfirmedServiceRequestConfirmedPrivateTransfer(
+		readWriteModel.CreateBACnetVendorIdContextTagged(0, 0),     // TODO: get right values
+		readWriteModel.CreateBACnetContextTagUnsignedInteger(1, 0), // TODO: get right values
+		nil,
+		0,
+	))
+	options = AddLeafTypeIfAbundant(options, c)
 	var err error
-	c.ConfirmedRequestSequence, err = NewConfirmedRequestSequence(args, kwArgs, WithConfirmedRequestSequenceExtension(c))
+	c.ConfirmedRequestSequence, err = NewConfirmedRequestSequence(args, kwArgs, Combine(options, WithConfirmedRequestSequenceExtension(c))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error building confirmed request")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestPDU.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestPDU.go
index 29a98d9..57c0389 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestPDU.go
@@ -34,13 +34,13 @@
 
 var _ readWriteModel.APDUConfirmedRequest = (*ConfirmedRequestPDU)(nil)
 
-func NewConfirmedRequestPDU(args Args, kwArgs KWArgs) (*ConfirmedRequestPDU, error) {
+func NewConfirmedRequestPDU(args Args, kwArgs KWArgs, options ...Option) (*ConfirmedRequestPDU, error) {
 	c := &ConfirmedRequestPDU{}
 	choice, ok := KWO[*readWriteModel.BACnetConfirmedServiceChoice](kwArgs, KWConfirmedServiceChoice, nil)
 	if _debug != nil {
 		_debug("__init__ %r %r %r", choice, args, kwArgs)
 	}
-	apdu, err := New_APDU(args, kwArgs)
+	apdu, err := New_APDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APDU")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestSequence.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestSequence.go
index 2346bd1..c2d2910 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestSequence.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ConfirmedRequestSequence.go
@@ -46,28 +46,27 @@
 	_contract ConfirmedRequestSequenceContract
 }
 
-func NewConfirmedRequestSequence(args Args, kwArgs KWArgs, opts ...func(*ConfirmedRequestSequence)) (*ConfirmedRequestSequence, error) {
+func NewConfirmedRequestSequence(args Args, kwArgs KWArgs, options ...Option) (*ConfirmedRequestSequence, error) {
 	u := &ConfirmedRequestSequence{}
-	for _, opt := range opts {
-		opt(u)
-	}
+	ApplyAppliers(options, u)
 	if u._contract == nil {
 		u._contract = u
 	} else {
 		u._contract.(ConfirmedRequestSequenceContractRequirement).SetConfirmedRequestSequence(u)
 	}
-	var err error
+	options = AddSharedSuperIfAbundant[_APCI](options)
+	options = AddLeafTypeIfAbundant(options, u)
 	kwArgs[KWConfirmedServiceChoice] = u._contract.GetServiceChoice()
-	u.ConfirmedRequestPDU, err = NewConfirmedRequestPDU(args, kwArgs)
+	var err error
+	u.ConfirmedRequestPDU, err = NewConfirmedRequestPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating ConfirmedRequestPDU")
 	}
-	u.APCISequence, err = NewAPCISequence(args, kwArgs, WithAPCISequenceExtension(u._contract))
+	//TODO: the sequence is usually init first but seems upstream does a init on the same level first before going deeper
+	u.APCISequence, err = NewAPCISequence(args, kwArgs, Combine(options, WithAPCISequenceExtension(u._contract))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APCISequence")
 	}
-	// We need to set the APCI to the same objects...
-	u.APCISequence._APCI = u.ConfirmedRequestPDU._APCI
 	if u.GetRootMessage() == nil {
 		panic("this should be set by NewConfirmedRequestPDU")
 		serviceRequest, _ := GAO[model.BACnetConfirmedServiceRequest](args, 0, nil)
@@ -79,10 +78,8 @@
 	return u, nil
 }
 
-func WithConfirmedRequestSequenceExtension(contract ConfirmedRequestSequenceContractRequirement) func(*ConfirmedRequestSequence) {
-	return func(a *ConfirmedRequestSequence) {
-		a._contract = contract
-	}
+func WithConfirmedRequestSequenceExtension(contract ConfirmedRequestSequenceContractRequirement) GenericApplier[*ConfirmedRequestSequence] {
+	return WrapGenericApplier(func(a *ConfirmedRequestSequence) { a._contract = contract })
 }
 
 func (u *ConfirmedRequestSequence) SetAPCISequence(a *APCISequence) {
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorPDU.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorPDU.go
index 433a5c5..8bdbb9b 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorPDU.go
@@ -34,7 +34,7 @@
 
 var _ readWriteModel.APDUError = (*ErrorPDU)(nil)
 
-func NewErrorPDU(args Args, kwArgs KWArgs) (*ErrorPDU, error) {
+func NewErrorPDU(args Args, kwArgs KWArgs, options ...Option) (*ErrorPDU, error) {
 	e := &ErrorPDU{}
 	choice, ok := KWO[*readWriteModel.BACnetConfirmedServiceChoice](kwArgs, KWConfirmedServiceChoice, nil)
 	invokeID, ok := KWO[*uint8](kwArgs, KWInvokedID, nil)
@@ -42,7 +42,8 @@
 	if _debug != nil {
 		_debug("__init__ %r %r %r %r %r", choice, invokeID, context, args, kwArgs)
 	}
-	apdu, err := New_APDU(args, kwArgs)
+	options = AddLeafTypeIfAbundant(options, e)
+	apdu, err := New_APDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APDU")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorSequence.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorSequence.go
index 2d09e95..19de44c 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorSequence.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ErrorSequence.go
@@ -46,23 +46,22 @@
 	_contract ErrorSequenceContract
 }
 
-func NewErrorSequence(args Args, kwArgs KWArgs, opts ...func(*ErrorSequence)) (*ErrorSequence, error) {
+func NewErrorSequence(args Args, kwArgs KWArgs, options ...Option) (*ErrorSequence, error) {
 	e := &ErrorSequence{}
-	for _, opt := range opts {
-		opt(e)
-	}
+	ApplyAppliers(options, e)
 	if e._contract == nil {
 		e._contract = e
 	} else {
 		e._contract.(ErrorSequenceContractRequirement).SetErrorSequence(e)
 	}
+	options = AddLeafTypeIfAbundant(options, e)
 	var err error
 	kwArgs[KWConfirmedServiceChoice] = e._contract.GetErrorChoice()
-	e.ErrorPDU, err = NewErrorPDU(args, kwArgs)
+	e.ErrorPDU, err = NewErrorPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating ErrorPDU")
 	}
-	e.APCISequence, err = NewAPCISequence(args, kwArgs, WithAPCISequenceExtension(e._contract))
+	e.APCISequence, err = NewAPCISequence(args, kwArgs, Combine(options, WithAPCISequenceExtension(e._contract))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APCISequence")
 	}
@@ -71,10 +70,8 @@
 	return e, nil
 }
 
-func WithErrorSequenceExtension(contract ErrorSequenceContractRequirement) func(*ErrorSequence) {
-	return func(a *ErrorSequence) {
-		a._contract = contract
-	}
+func WithErrorSequenceExtension(contract ErrorSequenceContractRequirement) GenericApplier[*ErrorSequence] {
+	return WrapGenericApplier(func(a *ErrorSequence) { a._contract = contract })
 }
 
 func (u *ErrorSequence) SetAPCISequence(a *APCISequence) {
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_EventNotificationParameters.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_EventNotificationParameters.go
index 39a5daa..2273f24 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_EventNotificationParameters.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_EventNotificationParameters.go
@@ -19,6 +19,12 @@
 
 package apdu
 
+import "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+
 // TODO: implement it...
 type EventNotificationParameters struct {
 }
+
+func NewEventNotificationParameters(arg comp.Arg) (*EventNotificationParameters, error) {
+	panic("Not implemented")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_IAmRequest.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_IAmRequest.go
index 269d921..2a9e5a9 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_IAmRequest.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_IAmRequest.go
@@ -36,7 +36,7 @@
 	sequenceElements []Element
 }
 
-func NewIAmRequest(args Args, kwArgs KWArgs) (*IAmRequest, error) {
+func NewIAmRequest(args Args, kwArgs KWArgs, options ...Option) (*IAmRequest, error) {
 	w := &IAmRequest{
 		serviceChoice: readWriteModel.BACnetUnconfirmedServiceChoice_WHO_IS,
 		sequenceElements: []Element{
@@ -46,17 +46,16 @@
 			NewElement("vendorID", V2E(NewUnsigned)),
 		},
 	}
-	if _, ok := kwArgs[KWCompRootMessage]; !ok {
-		kwArgs[KWCompRootMessage] = readWriteModel.NewBACnetUnconfirmedServiceRequestIAm(
-			readWriteModel.CreateBACnetApplicationTagObjectIdentifier(0, 0),                                                // TODO: get right values
-			readWriteModel.CreateBACnetApplicationTagUnsignedInteger(0),                                                    // TODO: get right values
-			readWriteModel.NewBACnetSegmentationTagged(readWriteModel.CreateBACnetTagHeaderBalanced(false, 0, 0), 0, 0, 0), // TODO: get right values
-			readWriteModel.CreateBACnetVendorIdApplicationTagged(0),                                                        // TODO: get right values
-			0,
-		)
-	}
+	options = AddRootMessageIfAbundant(options, readWriteModel.NewBACnetUnconfirmedServiceRequestIAm(
+		readWriteModel.CreateBACnetApplicationTagObjectIdentifier(0, 0),                                                // TODO: get right values
+		readWriteModel.CreateBACnetApplicationTagUnsignedInteger(0),                                                    // TODO: get right values
+		readWriteModel.NewBACnetSegmentationTagged(readWriteModel.CreateBACnetTagHeaderBalanced(false, 0, 0), 0, 0, 0), // TODO: get right values
+		readWriteModel.CreateBACnetVendorIdApplicationTagged(0),                                                        // TODO: get right values
+		0,
+	))
+	options = AddLeafTypeIfAbundant(options, w)
 	var err error
-	w.UnconfirmedRequestSequence, err = NewUnconfirmedRequestSequence(args, kwArgs, WithUnconfirmedRequestSequenceExtension(w))
+	w.UnconfirmedRequestSequence, err = NewUnconfirmedRequestSequence(args, kwArgs, Combine(options, WithUnconfirmedRequestSequenceExtension(w))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating UnconfirmedRequestSequence")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessResult.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessResult.go
index f26fff1..606c59e 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessResult.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessResult.go
@@ -19,6 +19,12 @@
 
 package apdu
 
+import "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+
 // TODO: implement it...
 type ReadAccessResult struct {
 }
+
+func NewReadAccessResult(arg comp.Arg) (*ReadAccessResult, error) {
+	panic("implement me")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessSpecification.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessSpecification.go
index 384df53..3807879 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessSpecification.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_ReadAccessSpecification.go
@@ -19,6 +19,12 @@
 
 package apdu
 
+import "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+
 // TODO: implement it...
 type ReadAccessSpecification struct {
 }
+
+func NewReadAccessSpecification(arg comp.Arg) (*ReadAccessSpecification, error) {
+	panic("implement me")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestPDU.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestPDU.go
index 16c8345..d30bb00 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestPDU.go
@@ -34,13 +34,14 @@
 
 var _ readWriteModel.APDUUnconfirmedRequest = (*UnconfirmedRequestPDU)(nil)
 
-func NewUnconfirmedRequestPDU(args Args, kwArgs KWArgs) (*UnconfirmedRequestPDU, error) {
+func NewUnconfirmedRequestPDU(args Args, kwArgs KWArgs, options ...Option) (*UnconfirmedRequestPDU, error) {
 	u := &UnconfirmedRequestPDU{}
 	choice, ok := KWO[*readWriteModel.BACnetUnconfirmedServiceChoice](kwArgs, KWUnconfirmedServiceChoice, nil)
 	if _debug != nil {
 		_debug("__init__ %r %r %r", choice, args, kwArgs)
 	}
-	apdu, err := New_APDU(args, kwArgs)
+	options = AddLeafTypeIfAbundant(options, u)
+	apdu, err := New_APDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APDU")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestSequence.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestSequence.go
index 63eb0ba..ad6f878 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestSequence.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_UnconfirmedRequestSequence.go
@@ -46,28 +46,30 @@
 	_contract UnconfirmedRequestSequenceContract
 }
 
-func NewUnconfirmedRequestSequence(args Args, kwArgs KWArgs, opts ...func(*UnconfirmedRequestSequence)) (*UnconfirmedRequestSequence, error) {
+func NewUnconfirmedRequestSequence(args Args, kwArgs KWArgs, options ...Option) (*UnconfirmedRequestSequence, error) {
 	u := &UnconfirmedRequestSequence{}
-	for _, opt := range opts {
-		opt(u)
+	ApplyAppliers(options, u)
+	if _debug != nil {
+		_debug("__init__ %r %r", args, kwArgs)
 	}
 	if u._contract == nil {
 		u._contract = u
 	} else {
 		u._contract.(UnconfirmedRequestSequenceContractRequirement).SetUnconfirmedRequestSequence(u)
 	}
+	options = AddSharedSuperIfAbundant[_APCI](options)
+	options = AddLeafTypeIfAbundant(options, u)
 	var err error
 	kwArgs[KWUnconfirmedServiceChoice] = u._contract.GetServiceChoice()
-	u.UnconfirmedRequestPDU, err = NewUnconfirmedRequestPDU(args, kwArgs)
+	u.UnconfirmedRequestPDU, err = NewUnconfirmedRequestPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating UnconfirmedRequestPDU")
 	}
-	u.APCISequence, err = NewAPCISequence(args, kwArgs, WithAPCISequenceExtension(u._contract))
+	//TODO: the sequence is usually init first but seems upstream does a init on the same level first before going deeper
+	u.APCISequence, err = NewAPCISequence(args, kwArgs, Combine(options, WithAPCISequenceExtension(u._contract))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating _APCISequence")
 	}
-	// We need to set the APCI to the same objects...
-	u.APCISequence._APCI = u.UnconfirmedRequestPDU._APCI
 	if u.GetRootMessage() == nil {
 		panic("this should be set by NewConfirmedRequestPDU")
 		serviceRequest, _ := GAO[model.BACnetConfirmedServiceRequest](args, 0, nil)
@@ -79,10 +81,8 @@
 	return u, nil
 }
 
-func WithUnconfirmedRequestSequenceExtension(contract UnconfirmedRequestSequenceContractRequirement) func(*UnconfirmedRequestSequence) {
-	return func(a *UnconfirmedRequestSequence) {
-		a._contract = contract
-	}
+func WithUnconfirmedRequestSequenceExtension(contract UnconfirmedRequestSequenceContractRequirement) GenericApplier[*UnconfirmedRequestSequence] {
+	return WrapGenericApplier(func(a *UnconfirmedRequestSequence) { a._contract = contract })
 }
 
 func (u *UnconfirmedRequestSequence) SetAPCISequence(a *APCISequence) {
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_WhoIsRequest.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_WhoIsRequest.go
index ed77da1..e0da439 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu_WhoIsRequest.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu_WhoIsRequest.go
@@ -37,7 +37,7 @@
 
 var _ readWriteModel.APDUUnconfirmedRequest = (*WhoIsRequest)(nil)
 
-func NewWhoIsRequest(args Args, kwArgs KWArgs) (*WhoIsRequest, error) {
+func NewWhoIsRequest(args Args, kwArgs KWArgs, options ...Option) (*WhoIsRequest, error) {
 	w := &WhoIsRequest{
 		serviceChoice: readWriteModel.BACnetUnconfirmedServiceChoice_WHO_IS,
 		sequenceElements: []Element{
@@ -45,15 +45,14 @@
 			NewElement("deviceInstanceRangeHighLimit", V2E(NewUnsigned), WithElementContext(1), WithElementOptional(true)),
 		},
 	}
-	if _, ok := kwArgs[KWCompRootMessage]; !ok {
-		kwArgs[KWCompRootMessage] = readWriteModel.NewBACnetUnconfirmedServiceRequestWhoIs(
-			readWriteModel.CreateBACnetContextTagUnsignedInteger(0, 0), // TODO: set the right values
-			readWriteModel.CreateBACnetContextTagUnsignedInteger(1, 0), // TODO: set the right values
-			0,
-		)
-	}
+	options = AddRootMessageIfAbundant(options, readWriteModel.NewBACnetUnconfirmedServiceRequestWhoIs(
+		readWriteModel.CreateBACnetContextTagUnsignedInteger(0, 0), // TODO: set the right values
+		readWriteModel.CreateBACnetContextTagUnsignedInteger(1, 0), // TODO: set the right values
+		0,
+	))
+	options = AddLeafTypeIfAbundant(options, w)
 	var err error
-	w.UnconfirmedRequestSequence, err = NewUnconfirmedRequestSequence(args, kwArgs, WithUnconfirmedRequestSequenceExtension(w))
+	w.UnconfirmedRequestSequence, err = NewUnconfirmedRequestSequence(args, kwArgs, Combine(options, WithUnconfirmedRequestSequenceExtension(w))...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating UnconfirmedRequestSequence")
 	}
@@ -78,3 +77,11 @@
 func (w *WhoIsRequest) SetUnconfirmedRequestSequence(u *UnconfirmedRequestSequence) {
 	w.UnconfirmedRequestSequence = u
 }
+
+func (w *WhoIsRequest) SetDeviceInstanceRangeLowLimit(u uint) {
+	panic("implement me")
+}
+
+func (w *WhoIsRequest) SetDeviceInstanceRangeHighLimit(u uint) {
+	panic("implement me")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/apdu/apdu__APDU.go b/plc4go/internal/bacnetip/bacgopes/apdu/apdu__APDU.go
index 04c0fb3..cd37c94 100644
--- a/plc4go/internal/bacnetip/bacgopes/apdu/apdu__APDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/apdu/apdu__APDU.go
@@ -38,14 +38,19 @@
 
 type ___APDU struct {
 	*__APDU
+
+	_leafType string
 }
 
 var _ _APDU = (*___APDU)(nil)
 
-func New_APDU(args Args, kwArgs KWArgs) (_APDU, error) {
-	i := &___APDU{}
+func New_APDU(args Args, kwArgs KWArgs, options ...Option) (_APDU, error) {
+	i := &___APDU{
+		_leafType: ExtractLeafName(options, "APDU"),
+	}
+	options = AddLeafTypeIfAbundant(options, i)
 	var err error
-	apdu, err := NewAPDU(args, kwArgs)
+	apdu, err := NewAPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating APDU")
 	}
@@ -102,7 +107,7 @@
 func (a *___APDU) Format(s fmt.State, v rune) {
 	switch v {
 	case 'v', 's', 'r':
-		sname := fmt.Sprintf("%T", a)
+		sname := a._leafType
 
 		// the type is the service
 		stype := ""
@@ -117,6 +122,7 @@
 			stype += ", " + strconv.Itoa(int(*a.apduInvokeID))
 		}
 		// put it together
-		_, _ = fmt.Fprintf(s, "<%s(%s) instance at %p>", sname, stype, a)
+		_, _ = fmt.Fprintf(s, "<%s(%s) instance at %p>\n", sname, stype, a)
 	}
+	a.PrintDebugContents(2, s, nil)
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/app/app_Application.go b/plc4go/internal/bacnetip/bacgopes/app/app_Application.go
index d86a8e8..32271e3 100644
--- a/plc4go/internal/bacnetip/bacgopes/app/app_Application.go
+++ b/plc4go/internal/bacnetip/bacgopes/app/app_Application.go
@@ -45,9 +45,9 @@
 	ApplicationServiceElementContract
 	Collector
 
-	objectName       map[string]*LocalDeviceObject
-	objectIdentifier map[string]*LocalDeviceObject
-	localDevice      *LocalDeviceObject
+	objectName       map[string]LocalDeviceObject
+	objectIdentifier map[string]LocalDeviceObject
+	localDevice      LocalDeviceObject
 	localAddress     *Address
 	deviceInfoCache  *appservice.DeviceInfoCache
 	controllers      map[string]any
@@ -85,17 +85,17 @@
 	}
 
 	// local objects by ID and name
-	a.objectName = map[string]*LocalDeviceObject{}
-	a.objectIdentifier = map[string]*LocalDeviceObject{}
+	a.objectName = map[string]LocalDeviceObject{}
+	a.objectIdentifier = map[string]LocalDeviceObject{}
 
 	// keep track of the local device
 	if a.localDevice != nil {
 		// bind the device object to this application
-		a.localDevice.App = a
+		a.localDevice.SetApp(a)
 
 		// local objects by ID and name
-		a.objectName[a.localDevice.ObjectName] = a.localDevice
-		a.objectName[a.localDevice.ObjectIdentifier] = a.localDevice
+		a.objectName[a.localDevice.GetObjectName()] = a.localDevice
+		a.objectName[a.localDevice.GetObjectIdentifier()] = a.localDevice
 	}
 
 	// use the provided cache or make a default one
@@ -124,7 +124,7 @@
 	return a, nil
 }
 
-func WithApplicationLocalDeviceObject(localDevice *LocalDeviceObject) func(*Application) {
+func WithApplicationLocalDeviceObject(localDevice LocalDeviceObject) func(*Application) {
 	return func(a *Application) {
 		a.localDevice = localDevice
 	}
@@ -148,18 +148,18 @@
 }
 
 // AddObject adds an object to the local collection
-func (a *Application) AddObject(obj *LocalDeviceObject) error {
+func (a *Application) AddObject(obj LocalDeviceObject) error {
 	a.log.Debug().Stringer("obj", obj).Msg("AddObject")
 	if _debug != nil {
 		_debug("add_object %r", obj)
 	}
 
 	// extract the object name and identifier
-	objectName := obj.ObjectName
+	objectName := obj.GetObjectName()
 	if objectName == "" {
 		return errors.New("object name required")
 	}
-	objectIdentifier := obj.ObjectIdentifier
+	objectIdentifier := obj.GetObjectIdentifier()
 	if objectIdentifier == "" {
 		return errors.New("object identifier required")
 	}
@@ -178,25 +178,25 @@
 
 	// append the new object's identifier to the local device's object list if there is one and has an object list property
 	if a.localDevice != nil {
-		a.localDevice.ObjectList = append(a.localDevice.ObjectList, objectIdentifier)
+		a.localDevice.SetObjectList(append(a.localDevice.GetObjectList(), objectIdentifier))
 	}
 
 	// let the object know which application stack it belongs to
-	obj.App = a
+	obj.SetApp(a)
 
 	return nil
 }
 
 // DeleteObject deletes an object from the local collection
-func (a *Application) DeleteObject(obj *LocalDeviceObject) error {
+func (a *Application) DeleteObject(obj LocalDeviceObject) error {
 	a.log.Debug().Stringer("obj", obj).Msg("DeleteObject")
 	if _debug != nil {
 		_debug("delete_object %r", obj)
 	}
 
 	// extract the object name and identifier
-	objectName := obj.ObjectName
-	objectIdentifier := obj.ObjectIdentifier
+	objectName := obj.GetObjectName()
+	objectIdentifier := obj.GetObjectIdentifier()
 
 	// delete it from the application
 	delete(a.objectName, objectName)
@@ -205,35 +205,35 @@
 	// remove the object's identifier from the device's object list if there is one and has an object list property
 	if a.localDevice != nil {
 		foundIndex := -1
-		for i, s := range a.localDevice.ObjectList {
+		for i, s := range a.localDevice.GetObjectList() {
 			if s == objectIdentifier {
 				foundIndex = i
 			}
 		}
 		if foundIndex >= 0 {
-			a.localDevice.ObjectList = append(a.localDevice.ObjectList[0:foundIndex], a.localDevice.ObjectList[foundIndex+1:]...)
+			a.localDevice.SetObjectList(append(a.localDevice.GetObjectList()[0:foundIndex], a.localDevice.GetObjectList()[foundIndex+1:]...))
 		}
 	}
 
 	// make sure the object knows it's detached from an application
-	obj.App = nil
+	obj.SetApp(nil)
 
 	return nil
 }
 
 // GetObjectId returns a local object or None.
-func (a *Application) GetObjectId(objectId string) *LocalDeviceObject {
+func (a *Application) GetObjectId(objectId string) LocalDeviceObject {
 	return a.objectIdentifier[objectId]
 }
 
 // GetObjectName returns a local object or None.
-func (a *Application) GetObjectName(objectName string) *LocalDeviceObject {
+func (a *Application) GetObjectName(objectName string) LocalDeviceObject {
 	return a.objectName[objectName]
 }
 
 // IterObjects iterates over the objects
-func (a *Application) IterObjects() []*LocalDeviceObject {
-	localDeviceObjects := make([]*LocalDeviceObject, 0, len(a.objectIdentifier))
+func (a *Application) IterObjects() []LocalDeviceObject {
+	localDeviceObjects := make([]LocalDeviceObject, 0, len(a.objectIdentifier))
 	for _, object := range a.objectIdentifier {
 		localDeviceObjects = append(localDeviceObjects, object)
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/app/app_ApplicationIOController.go b/plc4go/internal/bacnetip/bacgopes/app/app_ApplicationIOController.go
index f083703..0b4d0be 100644
--- a/plc4go/internal/bacnetip/bacgopes/app/app_ApplicationIOController.go
+++ b/plc4go/internal/bacnetip/bacgopes/app/app_ApplicationIOController.go
@@ -45,7 +45,7 @@
 	log zerolog.Logger
 }
 
-func NewApplicationIOController(localLog zerolog.Logger, localDevice *LocalDeviceObject, opts ...func(controller *ApplicationIOController)) (*ApplicationIOController, error) {
+func NewApplicationIOController(localLog zerolog.Logger, localDevice LocalDeviceObject, opts ...func(controller *ApplicationIOController)) (*ApplicationIOController, error) {
 	a := &ApplicationIOController{
 		// queues for each address
 		queueByAddress: make(map[string]*SieveQueue),
diff --git a/plc4go/internal/bacnetip/bacgopes/app/app_Application_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/app/app_Application_plc4xgen.go
index b7fbe1b..11b98c9 100644
--- a/plc4go/internal/bacnetip/bacgopes/app/app_Application_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/app/app_Application_plc4xgen.go
@@ -59,23 +59,10 @@
 	}
 	for _name, elem := range d.objectName {
 		name := _name
+		_value := fmt.Sprintf("%v", elem)
 
-		var elem any = elem
-		if serializable, ok := elem.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext(name); err != nil {
-				return err
-			}
-			if err := serializable.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext(name); err != nil {
-				return err
-			}
-		} else {
-			elemAsString := fmt.Sprintf("%v", elem)
-			if err := writeBuffer.WriteString(name, uint32(len(elemAsString)*8), elemAsString); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString(name, uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if err := writeBuffer.PopContext("objectName", utils.WithRenderAsList(true)); err != nil {
@@ -86,35 +73,20 @@
 	}
 	for _name, elem := range d.objectIdentifier {
 		name := _name
+		_value := fmt.Sprintf("%v", elem)
 
-		var elem any = elem
-		if serializable, ok := elem.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext(name); err != nil {
-				return err
-			}
-			if err := serializable.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext(name); err != nil {
-				return err
-			}
-		} else {
-			elemAsString := fmt.Sprintf("%v", elem)
-			if err := writeBuffer.WriteString(name, uint32(len(elemAsString)*8), elemAsString); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString(name, uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if err := writeBuffer.PopContext("objectIdentifier", utils.WithRenderAsList(true)); err != nil {
 		return err
 	}
-	if d.localDevice != nil {
-		{
-			_value := fmt.Sprintf("%v", d.localDevice)
+	{
+		_value := fmt.Sprintf("%v", d.localDevice)
 
-			if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if d.localAddress != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/app/app_BIPForeignApplication.go b/plc4go/internal/bacnetip/bacgopes/app/app_BIPForeignApplication.go
index 680c24c..03f49d3 100644
--- a/plc4go/internal/bacnetip/bacgopes/app/app_BIPForeignApplication.go
+++ b/plc4go/internal/bacnetip/bacgopes/app/app_BIPForeignApplication.go
@@ -28,7 +28,6 @@
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/service"
 )
@@ -49,7 +48,7 @@
 	log zerolog.Logger
 }
 
-func NewBIPForeignApplication(localLog zerolog.Logger, localDevice *LocalDeviceObject, localAddress Address, bbmdAddress *Address, bbmdTTL *uint16, deviceInfoCache *DeviceInfoCache, aseID *int) (*BIPForeignApplication, error) {
+func NewBIPForeignApplication(localLog zerolog.Logger, localDevice LocalDeviceObject, localAddress Address, bbmdAddress *Address, bbmdTTL *uint16, deviceInfoCache *DeviceInfoCache, aseID *int) (*BIPForeignApplication, error) {
 	b := &BIPForeignApplication{
 		log: localLog,
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/app/app_BIPSimpleApplication.go b/plc4go/internal/bacnetip/bacgopes/app/app_BIPSimpleApplication.go
index 270aed6..7a2690b 100644
--- a/plc4go/internal/bacnetip/bacgopes/app/app_BIPSimpleApplication.go
+++ b/plc4go/internal/bacnetip/bacgopes/app/app_BIPSimpleApplication.go
@@ -28,7 +28,6 @@
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/service"
 )
@@ -51,7 +50,7 @@
 	log zerolog.Logger
 }
 
-func NewBIPSimpleApplication(localLog zerolog.Logger, localDevice *LocalDeviceObject, localAddress Address, deviceInfoCache *DeviceInfoCache, aseID *int) (*BIPSimpleApplication, error) {
+func NewBIPSimpleApplication(localLog zerolog.Logger, localDevice LocalDeviceObject, localAddress Address, deviceInfoCache *DeviceInfoCache, aseID *int) (*BIPSimpleApplication, error) {
 	b := &BIPSimpleApplication{
 		log: localLog,
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ApplicationServiceAccessPoint.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ApplicationServiceAccessPoint.go
index 743a696..cc89ad1 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ApplicationServiceAccessPoint.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ApplicationServiceAccessPoint.go
@@ -143,7 +143,7 @@
 			a.log.Debug().Err(errorFound).Msg("got error")
 
 			// TODO: map it to a error... code temporary placeholder
-			return a.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, readWriteModel.NewAPDUReject(_apdu.GetInvokeId(), nil, 0)))), NoKWArgs())
+			return a.Response(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(readWriteModel.NewAPDUReject(_apdu.GetInvokeId(), nil, 0)))), NoKWArgs())
 		}
 	case readWriteModel.APDUUnconfirmedRequest:
 		var apduService readWriteModel.BACnetUnconfirmedServiceChoice
@@ -173,7 +173,6 @@
 	return nil
 }
 
-// TODO: big WIP
 func (a *ApplicationServiceAccessPoint) SapIndication(args Args, kwArgs KWArgs) error {
 	a.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("SapIndication")
 	apdu := GA[APDU](args, 0)
@@ -207,6 +206,10 @@
 		return errors.Errorf("unknown _PDU type %T", apdu)
 	}
 
+	if _debug != nil {
+		_debug("    - xpdu %r", xpdu)
+	}
+
 	// forward the encoded packet
 	err := a.Request(NA(xpdu), NoKWArgs())
 	if err != nil {
@@ -215,7 +218,10 @@
 
 	// if the upper layers of the application did not assign an invoke ID,
 	// copy the one that was assigned on its way down the stack
-	if isConfirmed && apdu.GetApduInvokeID() != nil {
+	if isConfirmed && apdu.GetApduInvokeID() == nil {
+		if _debug != nil {
+			_debug("    - pass invoke ID upstream %r", xpdu.GetApduInvokeID())
+		}
 		apdu.SetApduInvokeID(xpdu.GetApduInvokeID())
 	}
 	return err
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ClientSSM.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ClientSSM.go
index b87b856..8d9a6af 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ClientSSM.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ClientSSM.go
@@ -91,7 +91,8 @@
 	apdu := GA[PDU](args, 0)
 
 	// make sure it has a good source and destination
-	apdu = NewPDU(NoArgs, NKW(KWCompRootMessage, apdu, KWCPCIDestination, c.pduAddress))
+	apdu.SetPDUSource(nil)
+	apdu.SetPDUDestination(c.pduAddress)
 
 	// send it via the device
 	return c.ssmSAP.Request(NA(apdu), kwArgs)
@@ -210,7 +211,8 @@
 	apdu := GA[PDU](args, 0)
 
 	// make sure it has a good source and destination
-	apdu = NewPDU(NoArgs, NKW(KWCompRootMessage, apdu, KWCPCISource, c.pduAddress))
+	apdu.SetPDUSource(nil)
+	apdu.SetPDUDestination(c.pduAddress)
 
 	// send it to the application
 	return c.ssmSAP.SapResponse(NA(apdu), kwArgs)
@@ -262,7 +264,7 @@
 	// build an abort _PDU to return
 	abortApdu := readWriteModel.NewAPDUAbort(false, c.invokeId, readWriteModel.NewBACnetAbortReasonTagged(reason, uint32(reason), 0), 0)
 	// return it
-	return NewPDU(NoArgs, NKW(KWCompRootMessage, abortApdu)), nil
+	return NewPDU(NoArgs, NoKWArgs(), WithRootMessage(abortApdu)), nil
 }
 
 // segmentedRequest This function is called when the client is sending a segmented request and receives an apdu
@@ -464,7 +466,7 @@
 
 			// send back a segment ack
 			segmentAck := readWriteModel.NewAPDUSegmentAck(false, false, c.invokeId, c.initialSequenceNumber, *c.actualWindowSize, 0)
-			if err := c.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segmentAck))), NoKWArgs()); err != nil {
+			if err := c.Request(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segmentAck))), NoKWArgs()); err != nil {
 				c.log.Debug().Err(err).Msg("error sending request")
 			}
 		} else {
@@ -503,7 +505,7 @@
 		// save the retry count, indication acts like the request is coming from the application so the retryCount gets
 		//            re-initialized.
 		saveCount := c.retryCount
-		if err := c.Indication(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, c.segmentAPDU.originalApdu, KWCPCIDestination, c.pduAddress))), NoKWArgs()); err != nil { // TODO: check that it is really the intention to re-send the original apdu here
+		if err := c.Indication(NA(NewPDU(NoArgs, NKW(KWCPCIDestination, c.pduAddress)), WithRootMessage(c.segmentAPDU.originalApdu)), NoKWArgs()); err != nil { // TODO: check that it is really the intention to re-send the original apdu here
 			return err
 		}
 		c.retryCount = saveCount
@@ -568,7 +570,7 @@
 		// segment received out of order
 		c.RestartTimer(c.segmentTimeout)
 		segmentAck := readWriteModel.NewAPDUSegmentAck(true, false, c.invokeId, c.initialSequenceNumber, *c.actualWindowSize, 0)
-		if err := c.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segmentAck))), NoKWArgs()); err != nil {
+		if err := c.Request(NA(NewPDU(NoArgs, NoKWArgs()), WithRootMessage(segmentAck)), NoKWArgs()); err != nil {
 			c.log.Debug().Err(err).Msg("error sending request")
 		}
 		return nil
@@ -588,7 +590,7 @@
 
 		// send final ack
 		segmentAck := readWriteModel.NewAPDUSegmentAck(false, false, c.invokeId, c.lastSequenceNumber, *c.actualWindowSize, 0)
-		if err := c.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segmentAck))), NoKWArgs()); err != nil {
+		if err := c.Request(NA(NewPDU(NoArgs, NoKWArgs()), WithRootMessage(segmentAck)), NoKWArgs()); err != nil {
 			c.log.Debug().Err(err).Msg("error sending request")
 		}
 
@@ -602,7 +604,7 @@
 		if err != nil {
 			return errors.Wrap(err, "error parsing apdu")
 		}
-		if err := c.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, parse))), NoKWArgs()); err != nil {
+		if err := c.Request(NA(NewPDU(NoArgs, NoKWArgs()), WithRootMessage(parse)), NoKWArgs()); err != nil {
 			c.log.Debug().Err(err).Msg("error sending response")
 		}
 	} else if *apduComplexAck.GetSequenceNumber() == c.initialSequenceNumber+*c.actualWindowSize {
@@ -611,7 +613,7 @@
 		c.initialSequenceNumber = c.lastSequenceNumber
 		c.RestartTimer(c.segmentTimeout)
 		segmentAck := readWriteModel.NewAPDUSegmentAck(false, false, c.invokeId, c.lastSequenceNumber, *c.actualWindowSize, 0)
-		if err := c.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segmentAck))), NoKWArgs()); err != nil { // send it ot the device
+		if err := c.Request(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segmentAck))), NoKWArgs()); err != nil { // send it ot the device
 			c.log.Debug().Err(err).Msg("error sending request")
 		}
 	} else {
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_SSM.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_SSM.go
index 3ce17f0..22697f6 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_SSM.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_SSM.go
@@ -81,7 +81,7 @@
 	ServiceAccessPointContract
 	Client
 	GetDeviceInfoCache() *DeviceInfoCache
-	GetLocalDevice() *LocalDeviceObject
+	GetLocalDevice() LocalDeviceObject
 	GetProposedWindowSize() uint8
 	GetClientTransactions() []*ClientSSM
 	RemoveClientTransaction(*ClientSSM)
@@ -145,36 +145,36 @@
 	}
 	localDevice := sap.GetLocalDevice()
 	var numberOfApduRetries uint
-	if localDevice.NumberOfAPDURetries != nil {
-		numberOfApduRetries = *localDevice.NumberOfAPDURetries
+	if localDevice.GetNumberOfAPDURetries() != nil {
+		numberOfApduRetries = *localDevice.GetNumberOfAPDURetries()
 	}
 	var apduTimeout uint
-	if localDevice.APDUTimeout != nil {
-		apduTimeout = *localDevice.APDUTimeout
+	if localDevice.GetAPDUTimeout() != nil {
+		apduTimeout = *localDevice.GetAPDUTimeout()
 	} else {
 		apduTimeout = sap.GetDefaultAPDUTimeout()
 	}
 	var segmentationSupported readWriteModel.BACnetSegmentation
-	if localDevice.SegmentationSupported != nil {
-		segmentationSupported = *localDevice.SegmentationSupported
+	if localDevice.GetSegmentationSupported() != nil {
+		segmentationSupported = *localDevice.GetSegmentationSupported()
 	} else {
 		segmentationSupported = sap.GetDefaultSegmentationSupported()
 	}
 	var segmentTimeout uint
-	if localDevice.APDUSegmentTimeout != nil {
-		segmentTimeout = *localDevice.APDUSegmentTimeout
+	if localDevice.GetAPDUSegmentTimeout() != nil {
+		segmentTimeout = *localDevice.GetAPDUSegmentTimeout()
 	} else {
 		segmentTimeout = sap.GetDefaultAPDUSegmentTimeout()
 	}
 	var maxSegmentsAccepted readWriteModel.MaxSegmentsAccepted
-	if localDevice.MaxSegmentsAccepted != nil {
-		maxSegmentsAccepted = *localDevice.MaxSegmentsAccepted
+	if localDevice.GetMaxSegmentsAccepted() != nil {
+		maxSegmentsAccepted = *localDevice.GetMaxSegmentsAccepted()
 	} else {
 		maxSegmentsAccepted = sap.GetDefaultMaxSegmentsAccepted()
 	}
 	var maxApduLengthAccepted readWriteModel.MaxApduLengthAccepted
-	if localDevice.MaximumApduLengthAccepted != nil {
-		maxApduLengthAccepted = *localDevice.MaximumApduLengthAccepted
+	if localDevice.GetMaximumApduLengthAccepted() != nil {
+		maxApduLengthAccepted = *localDevice.GetMaximumApduLengthAccepted()
 	} else {
 		maxApduLengthAccepted = sap.GetDefaultMaximumApduLengthAccepted()
 	}
@@ -291,7 +291,7 @@
 
 	// TODO: the original code does here something funky but it seems it is best to just return the original apdu
 	if s.segmentCount == 1 {
-		return NewPDU(NoArgs, NKW(KWCompRootMessage, s.segmentAPDU.originalApdu, KWCPCIDestination, s.pduAddress)), false, nil
+		return NewPDU(NoArgs, NKW(KWCPCIDestination, s.pduAddress), WithRootMessage(s.segmentAPDU.originalApdu)), false, nil
 	}
 
 	moreFollows = index < s.segmentCount-1
@@ -309,7 +309,7 @@
 		s.log.Debug().Msg("confirmed request context")
 		segmentedResponseAccepted := s.segmentationSupported == readWriteModel.BACnetSegmentation_SEGMENTED_RECEIVE || s.segmentationSupported == readWriteModel.BACnetSegmentation_SEGMENTED_BOTH
 		s.log.Debug().Bool("segmentedResponseAccepted", segmentedResponseAccepted).Msg("segmentedResponseAccepted")
-		segmentAPDU = NewPDU(NoArgs, NKW(KWCompRootMessage, readWriteModel.NewAPDUConfirmedRequest(
+		segmentAPDU = NewPDU(NoArgs, NKW(KWCPCIDestination, s.pduAddress), WithRootMessage(readWriteModel.NewAPDUConfirmedRequest(
 			true,
 			moreFollows,
 			segmentedResponseAccepted,
@@ -322,10 +322,10 @@
 			serviceChoice,
 			segmentBytes,
 			0,
-		), KWCPCIDestination, s.pduAddress))
+		)))
 	} else {
 		s.log.Debug().Msg("complex ack context")
-		segmentAPDU = NewPDU(NoArgs, NKW(KWCompRootMessage, readWriteModel.NewAPDUComplexAck(
+		segmentAPDU = NewPDU(NoArgs, NKW(KWCPCIDestination, s.pduAddress), WithRootMessage(readWriteModel.NewAPDUComplexAck(
 			true,
 			moreFollows,
 			s.segmentAPDU.originalInvokeId,
@@ -335,7 +335,7 @@
 			serviceChoice,
 			segmentBytes,
 			0,
-		), KWCPCIDestination, s.pduAddress))
+		)))
 	}
 	return segmentAPDU, moreFollows, nil
 }
@@ -383,7 +383,7 @@
 		if err != nil {
 			return errors.Wrapf(err, "Error sending out segment %d", i)
 		}
-		if err := s.ssmSAP.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, apdu.GetRootMessage(), KWCPCIDestination, s.pduAddress))), NoKWArgs()); err != nil {
+		if err := s.ssmSAP.Request(NA(NewPDU(NoArgs, NKW(KWCPCIDestination, s.pduAddress)), WithRootMessage(apdu.GetRootMessage())), NoKWArgs()); err != nil {
 			s.log.Debug().Err(err).Msg("error sending request")
 		}
 		if moreFollows {
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ServerSSM.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ServerSSM.go
index a6820c8..a28f530 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ServerSSM.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_ServerSSM.go
@@ -286,7 +286,7 @@
 	// build an abort _PDU to return
 	abortApdu := readWriteModel.NewAPDUAbort(true, s.invokeId, readWriteModel.NewBACnetAbortReasonTagged(reason, uint32(reason), 0), 0)
 	// return it
-	return NewPDU(NoArgs, NKW(KWCompRootMessage, abortApdu)), nil
+	return NewPDU(NoArgs, NoKWArgs(), WithRootMessage(abortApdu)), nil
 }
 
 func (s *ServerSSM) idle(apdu PDU) error {
@@ -390,7 +390,7 @@
 	// send back a segment ack
 	segack := readWriteModel.NewAPDUSegmentAck(false, true, s.invokeId, s.initialSequenceNumber, *s.actualWindowSize, 0)
 	s.log.Debug().Stringer("segack", segack).Msg("segAck")
-	return s.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segack))), NoKWArgs())
+	return s.Response(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segack))), NoKWArgs())
 }
 
 func (s *ServerSSM) segmentedRequest(apdu PDU) error {
@@ -447,7 +447,7 @@
 
 		// send back a segment ack
 		segack := readWriteModel.NewAPDUSegmentAck(true, true, s.invokeId, s.initialSequenceNumber, *s.actualWindowSize, 0)
-		return s.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segack))), NoKWArgs())
+		return s.Response(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segack))), NoKWArgs())
 	}
 
 	// add the data
@@ -464,7 +464,7 @@
 
 		// send back the final segment ack
 		segack := readWriteModel.NewAPDUSegmentAck(false, true, s.invokeId, s.lastSequenceNumber, *s.actualWindowSize, 0)
-		if err := s.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segack))), NoKWArgs()); err != nil {
+		if err := s.Response(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segack))), NoKWArgs()); err != nil {
 			s.log.Debug().Err(err).Msg("error sending response")
 		}
 
@@ -481,7 +481,7 @@
 		if err != nil {
 			return errors.Wrap(err, "error parsing apdu")
 		}
-		if err := s.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, parse))), NoKWArgs()); err != nil {
+		if err := s.Request(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(parse))), NoKWArgs()); err != nil {
 			s.log.Debug().Err(err).Msg("error sending request")
 		}
 	} else if *apduConfirmedRequest.GetSequenceNumber() == s.initialSequenceNumber+*s.actualWindowSize {
@@ -492,7 +492,7 @@
 
 		// send back a segment ack
 		segack := readWriteModel.NewAPDUSegmentAck(false, true, s.invokeId, s.initialSequenceNumber, *s.actualWindowSize, 0)
-		if err := s.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, segack))), NoKWArgs()); err != nil {
+		if err := s.Response(NA(NewPDU(NoArgs, NoKWArgs(), WithRootMessage(segack))), NoKWArgs()); err != nil {
 			s.log.Debug().Err(err).Msg("error sending response")
 		}
 	} else {
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint.go
index eadb4e4..e42b9df 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint.go
@@ -40,7 +40,7 @@
 	ServiceAccessPointContract
 	*DefaultRFormatter `ignore:"true"`
 
-	localDevice           *LocalDeviceObject
+	localDevice           LocalDeviceObject
 	deviceInfoCache       *DeviceInfoCache
 	nextInvokeId          uint8
 	clientTransactions    []*ClientSSM
@@ -63,7 +63,7 @@
 	log zerolog.Logger
 }
 
-func NewStateMachineAccessPoint(localLog zerolog.Logger, localDevice *LocalDeviceObject, opts ...func(*StateMachineAccessPoint)) (*StateMachineAccessPoint, error) {
+func NewStateMachineAccessPoint(localLog zerolog.Logger, localDevice LocalDeviceObject, opts ...func(*StateMachineAccessPoint)) (*StateMachineAccessPoint, error) {
 	s := &StateMachineAccessPoint{
 		DefaultRFormatter: NewDefaultRFormatter(),
 		// save a reference to the device information cache
@@ -191,6 +191,10 @@
 	return s.maxApduLengthAccepted
 }
 
+func (s *StateMachineAccessPoint) SetDeviceInfoCache(cache *DeviceInfoCache) {
+	s.deviceInfoCache = cache
+}
+
 // Confirmation Packets coming up the stack are APDU's
 func (s *StateMachineAccessPoint) Confirmation(args Args, kwArgs KWArgs) error { // TODO: note we need a special method here as we don't contain src in the apdu
 	s.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Confirmation")
@@ -508,7 +512,7 @@
 	return s.deviceInfoCache
 }
 
-func (s *StateMachineAccessPoint) GetLocalDevice() *LocalDeviceObject {
+func (s *StateMachineAccessPoint) GetLocalDevice() LocalDeviceObject {
 	return s.localDevice
 }
 
diff --git a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint_plc4xgen.go
index 3af8c6e..0c6f660 100644
--- a/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/appservice/appservice_StateMachineAccessPoint_plc4xgen.go
@@ -54,13 +54,11 @@
 	if err := d.ServiceAccessPointContract.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 		return err
 	}
-	if d.localDevice != nil {
-		{
-			_value := fmt.Sprintf("%v", d.localDevice)
+	{
+		_value := fmt.Sprintf("%v", d.localDevice)
 
-			if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if d.deviceInfoCache != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_ActionList.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_ActionList.go
index ea054df..394b428 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_ActionList.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_ActionList.go
@@ -32,7 +32,7 @@
 func NewActionList(arg Arg) (*ActionList, error) {
 	s := &ActionList{
 		sequenceElements: []Element{
-			NewElement("action", SequenceOf(NewActionCommand), WithElementContext(0)),
+			NewElement("action", SequenceOfE(NewActionCommand), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AssignedLandingCalls.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AssignedLandingCalls.go
index 69785d7..b4b587f 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AssignedLandingCalls.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AssignedLandingCalls.go
@@ -32,7 +32,7 @@
 func NewAssignedLandingCalls(arg Arg) (*AssignedLandingCalls, error) {
 	s := &AssignedLandingCalls{
 		sequenceElements: []Element{
-			NewElement("landingCalls", SequenceOf(NewAssignedLandingCallsLandingCalls), WithElementContext(0)),
+			NewElement("landingCalls", SequenceOfE(NewAssignedLandingCallsLandingCalls), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AuthenticationPolicy.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AuthenticationPolicy.go
index 48b056e..376317e 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AuthenticationPolicy.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_AuthenticationPolicy.go
@@ -33,7 +33,7 @@
 func NewAuthenticationPolicy(arg Arg) (*AuthenticationPolicy, error) {
 	s := &AuthenticationPolicy{
 		sequenceElements: []Element{
-			NewElement("policy", SequenceOf(NewAuthenticationPolicyPolicy), WithElementContext(0)),
+			NewElement("policy", SequenceOfE(NewAuthenticationPolicyPolicy), WithElementContext(0)),
 			NewElement("orderEnforced", V2E(NewBoolean), WithElementContext(1)),
 			NewElement("timeout", V2E(NewUnsigned), WithElementContext(2)),
 		},
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscription.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscription.go
index 56cf546..b6b62a1 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscription.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscription.go
@@ -37,7 +37,7 @@
 			NewElement("issueConfirmedNotifications", V2E(NewBoolean), WithElementContext(1)),
 			NewElement("timeRemaining", V2E(NewUnsigned), WithElementContext(2)),
 			NewElement("maxNotificationDelay", V2E(NewUnsigned), WithElementContext(3)),
-			NewElement("listOfCOVSubscriptionSpecifications", SequenceOf(NewCOVMultipleSubscriptionList), WithElementContext(4)),
+			NewElement("listOfCOVSubscriptionSpecifications", SequenceOfE(NewCOVMultipleSubscriptionList), WithElementContext(4)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscriptionList.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscriptionList.go
index f815247..15d3788 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscriptionList.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_COVMultipleSubscriptionList.go
@@ -34,7 +34,7 @@
 	s := &COVMultipleSubscriptionList{
 		sequenceElements: []Element{
 			NewElement("monitoredObjectIdentifier", Vs2E(NewObjectIdentifier), WithElementContext(0)),
-			NewElement("listOfCOVReferences", SequenceOf(NewCOVMultipleSubscriptionListOfCOVReference), WithElementContext(1)),
+			NewElement("listOfCOVReferences", SequenceOfE(NewCOVMultipleSubscriptionListOfCOVReference), WithElementContext(1)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_DailySchedule.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_DailySchedule.go
index 93ec1e0..84546a5 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_DailySchedule.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_DailySchedule.go
@@ -32,7 +32,7 @@
 func NewDailySchedule(arg Arg) (*DailySchedule, error) {
 	s := &DailySchedule{
 		sequenceElements: []Element{
-			NewElement("daySchedule", SequenceOf(NewTimeValue), WithElementContext(0)),
+			NewElement("daySchedule", SequenceOfE(NewTimeValue), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEvent.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEvent.go
index 046d5f8..271bc76 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEvent.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEvent.go
@@ -32,7 +32,7 @@
 func NewEventParameterAccessEvent(arg Arg) (*EventParameterAccessEvent, error) {
 	s := &EventParameterAccessEvent{
 		sequenceElements: []Element{
-			NewElement("accessEvent", SequenceOf(NewEventParameterAccessEventAccessEvent), WithElementContext(0)),
+			NewElement("accessEvent", SequenceOfE(NewEventParameterAccessEventAccessEvent), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEventAccessEvent.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEventAccessEvent.go
index 382522b..7f82653 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEventAccessEvent.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterAccessEventAccessEvent.go
@@ -32,7 +32,7 @@
 func NewEventParameterAccessEventAccessEvent(arg Arg) (*EventParameterAccessEventAccessEvent, error) {
 	s := &EventParameterAccessEventAccessEvent{
 		sequenceElements: []Element{
-			NewElement("listOfAccessEvents", SequenceOf(NewAccessEvent), WithElementContext(0)),
+			NewElement("listOfAccessEvents", SequenceOfE(NewAccessEvent), WithElementContext(0)),
 			NewElement("accessEventTimeReference", V2E(NewDeviceObjectPropertyReference), WithElementContext(1)),
 		},
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfBitstring.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfBitstring.go
index 2722d11..b96b12e 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfBitstring.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfBitstring.go
@@ -35,7 +35,7 @@
 		sequenceElements: []Element{
 			NewElement("timeDelay", V2E(NewUnsigned), WithElementContext(0)),
 			NewElement("bitmask", Vs2E(NewBitString), WithElementContext(1)),
-			NewElement("listOfBitstringValues", SequenceOfs(NewBitString), WithElementContext(2)),
+			NewElement("listOfBitstringValues", SequenceOfsE(NewBitString), WithElementContext(2)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfCharacterString.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfCharacterString.go
index 02daf9b..56ded66 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfCharacterString.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfCharacterString.go
@@ -34,7 +34,7 @@
 	s := &EventParameterChangeOfCharacterString{
 		sequenceElements: []Element{
 			NewElement("timeDelay", V2E(NewUnsigned), WithElementContext(0)),
-			NewElement("listOfAlarmValues", SequenceOf(NewCharacterString), WithElementContext(1)),
+			NewElement("listOfAlarmValues", SequenceOfE(NewCharacterString), WithElementContext(1)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfLifeSafety.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfLifeSafety.go
index 979384e..80e8053 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfLifeSafety.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfLifeSafety.go
@@ -34,8 +34,8 @@
 	s := &EventParameterChangeOfLifeSafety{
 		sequenceElements: []Element{
 			NewElement("timeDelay", V2E(NewUnsigned), WithElementContext(0)),
-			NewElement("listOfLifeSafetyAlarmValues", SequenceOf(NewLifeSafetyState), WithElementContext(1)),
-			NewElement("listOfAlarmValues", SequenceOf(NewLifeSafetyState), WithElementContext(2)),
+			NewElement("listOfLifeSafetyAlarmValues", SequenceOfE(NewLifeSafetyState), WithElementContext(1)),
+			NewElement("listOfAlarmValues", SequenceOfE(NewLifeSafetyState), WithElementContext(2)),
 			NewElement("modePropertyReference", V2E(NewDeviceObjectPropertyReference), WithElementContext(3)),
 		},
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfState.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfState.go
index 734dced..66d990a 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfState.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterChangeOfState.go
@@ -34,7 +34,7 @@
 	s := &EventParameterChangeOfState{
 		sequenceElements: []Element{
 			NewElement("timeDelay", V2E(NewUnsigned), WithElementContext(0)),
-			NewElement("listOfValues", SequenceOf(NewPropertyStates), WithElementContext(1)),
+			NewElement("listOfValues", SequenceOfE(NewPropertyStates), WithElementContext(1)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterExtended.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterExtended.go
index dd723f3..be9fb7d 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterExtended.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_EventParameterExtended.go
@@ -35,7 +35,7 @@
 		sequenceElements: []Element{
 			NewElement("vendorId", V2E(NewUnsigned), WithElementContext(0)),
 			NewElement("extendedEventType", V2E(NewUnsigned), WithElementContext(1)),
-			NewElement("parameters", SequenceOf(NewEventParameterExtendedParameters), WithElementContext(2)),
+			NewElement("parameters", SequenceOfE(NewEventParameterExtendedParameters), WithElementContext(2)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterCharacterString.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterCharacterString.go
index a1fbc08..9927d59 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterCharacterString.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterCharacterString.go
@@ -33,7 +33,7 @@
 func NewFaultParameterCharacterString(arg Arg) (*FaultParameterCharacterString, error) {
 	s := &FaultParameterCharacterString{
 		sequenceElements: []Element{
-			NewElement("listOfFaultValues", SequenceOf(NewCharacterString), WithElementContext(0)),
+			NewElement("listOfFaultValues", SequenceOfE(NewCharacterString), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterExtended.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterExtended.go
index 4df9059..fd97269 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterExtended.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterExtended.go
@@ -35,7 +35,7 @@
 		sequenceElements: []Element{
 			NewElement("vendorId", V2E(NewUnsigned), WithElementContext(0)),
 			NewElement("extendedFaultType", V2E(NewUnsigned), WithElementContext(1)),
-			NewElement("parameters", SequenceOf(NewFaultParameterExtendedParameters), WithElementContext(2)),
+			NewElement("parameters", SequenceOfE(NewFaultParameterExtendedParameters), WithElementContext(2)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterLifeSafety.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterLifeSafety.go
index 75d9da3..d08175d 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterLifeSafety.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterLifeSafety.go
@@ -32,7 +32,7 @@
 func NewFaultParameterLifeSafety(arg Arg) (*FaultParameterLifeSafety, error) {
 	s := &FaultParameterLifeSafety{
 		sequenceElements: []Element{
-			NewElement("listOfFaultValues", SequenceOf(NewLifeSafetyState), WithElementContext(0)),
+			NewElement("listOfFaultValues", SequenceOfE(NewLifeSafetyState), WithElementContext(0)),
 			NewElement("modePropertyReference", V2E(NewDeviceObjectPropertyReference), WithElementContext(1)),
 		},
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterState.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterState.go
index 3f29b0a..16d78f8 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterState.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_FaultParameterState.go
@@ -32,7 +32,7 @@
 func NewFaultParameterState(arg Arg) (*FaultParameterState, error) {
 	s := &FaultParameterState{
 		sequenceElements: []Element{
-			NewElement("listOfFaultValues", SequenceOf(NewPropertyStates), WithElementContext(0)),
+			NewElement("listOfFaultValues", SequenceOfE(NewPropertyStates), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LandingDoorStatus.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LandingDoorStatus.go
index 9ad3010..f54f5e6 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LandingDoorStatus.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LandingDoorStatus.go
@@ -32,7 +32,7 @@
 func NewLandingDoorStatus(arg Arg) (*LandingDoorStatus, error) {
 	s := &LandingDoorStatus{
 		sequenceElements: []Element{
-			NewElement("landingDoors", SequenceOf(NewLandingDoorStatusLandingDoor), WithElementContext(0)),
+			NewElement("landingDoors", SequenceOfE(NewLandingDoorStatusLandingDoor), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LiftCarCallList.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LiftCarCallList.go
index fc1c0ed..0fc4e72 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LiftCarCallList.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LiftCarCallList.go
@@ -33,7 +33,7 @@
 func NewLiftCarCallList(arg Arg) (*LiftCarCallList, error) {
 	s := &LiftCarCallList{
 		sequenceElements: []Element{
-			NewElement("floorNumbers", SequenceOf(NewUnsigned8), WithElementContext(0)),
+			NewElement("floorNumbers", SequenceOfE(NewUnsigned8), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LogData.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LogData.go
index 7c97ac4..dcebbe1 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LogData.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_LogData.go
@@ -34,7 +34,7 @@
 	s := &LogData{
 		choiceElements: []Element{
 			NewElement("logStatus", V2E(NewLogStatus), WithElementContext(0)),
-			NewElement("logData", SequenceOf(NewLogDataLogData), WithElementContext(1)),
+			NewElement("logData", SequenceOfE(NewLogDataLogData), WithElementContext(1)),
 			NewElement("timeChange", V2E(NewReal), WithElementContext(2)),
 		},
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NameValueCollection.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NameValueCollection.go
index fe1086f..36d6496 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NameValueCollection.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NameValueCollection.go
@@ -32,7 +32,7 @@
 func NewNameValueCollection(arg Arg) (*NameValueCollection, error) {
 	s := &NameValueCollection{
 		sequenceElements: []Element{
-			NewElement("members", SequenceOfs(NewNameValue), WithElementContext(0)),
+			NewElement("members", SequenceOfsE(NewNameValue), WithElementContext(0)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NotificationParametersChangeOfReliabilityType.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NotificationParametersChangeOfReliabilityType.go
index 9358139..ce0d17a 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NotificationParametersChangeOfReliabilityType.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_NotificationParametersChangeOfReliabilityType.go
@@ -34,7 +34,7 @@
 		sequenceElements: []Element{
 			NewElement("reliability", V2E(NewReliability), WithElementContext(0)),
 			NewElement("statusFlags", V2E(NewStatusFlags), WithElementContext(1)),
-			NewElement("propertyValues", SequenceOf(NewPropertyValue), WithElementContext(2)),
+			NewElement("propertyValues", SequenceOfE(NewPropertyValue), WithElementContext(2)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_PriorityArray.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_PriorityArray.go
index a6ae20e..0e736dd 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_PriorityArray.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_PriorityArray.go
@@ -29,7 +29,7 @@
 
 func NewPriorityArray(arg Arg) (*PriorityArray, error) {
 	s := &PriorityArray{}
-	ArrayOf(NewPriorityValue, 16, PriorityValue{})
+	ArrayOfE(NewPriorityValue, 16, PriorityValue{})
 	panic("implementchoice")
 	return s, nil
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SecurityKeySet.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SecurityKeySet.go
index e93deaf..d220069 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SecurityKeySet.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SecurityKeySet.go
@@ -36,7 +36,7 @@
 			NewElement("keyRevision", V2E(NewUnsigned), WithElementContext(0)),
 			NewElement("activationTime", V2E(NewDateTime), WithElementContext(1)),
 			NewElement("expirationTime", V2E(NewDateTime), WithElementContext(2)),
-			NewElement("keyIds", SequenceOf(NewKeyIdentifier), WithElementContext(3)),
+			NewElement("keyIds", SequenceOfE(NewKeyIdentifier), WithElementContext(3)),
 		},
 	}
 	panic("implementchoice")
diff --git a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SpecialEvent.go b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SpecialEvent.go
index bf6ba1d..213f0b4 100644
--- a/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SpecialEvent.go
+++ b/plc4go/internal/bacnetip/bacgopes/basetypes/basetypes_SpecialEvent.go
@@ -34,7 +34,7 @@
 	s := &SpecialEvent{
 		sequenceElements: []Element{
 			NewElement("period", V2E(NewSpecialEventPeriod)),
-			NewElement("listOfTimeValues", SequenceOf(NewTimeValue), WithElementContext(2)),
+			NewElement("listOfTimeValues", SequenceOfE(NewTimeValue), WithElementContext(2)),
 			NewElement("eventPriority", V2E(NewUnsigned), WithElementContext(3)),
 		},
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLCI.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLCI.go
index 5c1421a..15447e5 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLCI.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLCI.go
@@ -66,7 +66,7 @@
 
 var _ BVLCI = (*_BVLCI)(nil)
 
-func NewBVLCI(requirements BVLCIRequirements, args Args, kwArgs KWArgs) BVLCI {
+func NewBVLCI(requirements BVLCIRequirements, args Args, kwArgs KWArgs, options ...Option) BVLCI {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
@@ -75,10 +75,11 @@
 
 		bvlciType: 0x81,
 	}
+	options = AddLeafTypeIfAbundant(options, b)
 	b.DebugContents = NewDebugContents(b, "bvlciType", "bvlciFunction", "bvlciLength")
 	b.PCI = NewPCI(args, kwArgs)
 	b.AddExtraPrinters(b.PCI.(DebugContentPrinter))
-	if bvlc, ok := KWO[readWriteModel.BVLC](kwArgs, KWCompRootMessage, nil); ok {
+	if bvlc, ok := ExtractRootMessage(options).(readWriteModel.BVLC); ok {
 		b.bvlciFunction = bvlc.GetBvlcFunction()
 		b.bvlciLength = bvlc.GetLengthInBytes(context.Background())
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLPDU.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLPDU.go
index b96af06..d37f30f 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_BVLPDU.go
@@ -44,13 +44,14 @@
 
 var _ BVLPDU = (*_BVLPDU)(nil)
 
-func NewBVLPDU(args Args, kwArgs KWArgs) BVLPDU {
+func NewBVLPDU(args Args, kwArgs KWArgs, options ...Option) BVLPDU {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
 	b := &_BVLPDU{}
-	b._BVLCI = NewBVLCI(b, args, kwArgs).(*_BVLCI)
-	b.PDUData = NewPDUData(args, kwArgs)
+	options = AddLeafTypeIfAbundant(options, b)
+	b._BVLCI = NewBVLCI(b, args, kwArgs, options...).(*_BVLCI)
+	b.PDUData = NewPDUData(args, kwArgs, options...)
 	b.AddExtraPrinters(b.PDUData.(DebugContentPrinter))
 	if b.GetRootMessage() != nil {
 		data, _ := b.GetRootMessage().Serialize()
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DeleteForeignDeviceTableEntry.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DeleteForeignDeviceTableEntry.go
index 0d61f6e..3581cc5 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DeleteForeignDeviceTableEntry.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DeleteForeignDeviceTableEntry.go
@@ -38,9 +38,11 @@
 
 var _ BVLPDU = (*DeleteForeignDeviceTableEntry)(nil)
 
-func NewDeleteForeignDeviceTableEntry(addr *Address, args Args, kwArgs KWArgs) (*DeleteForeignDeviceTableEntry, error) {
+// TODO: check this args no args desaster...
+func NewDeleteForeignDeviceTableEntry(addr *Address, args Args, kwArgs KWArgs, options ...Option) (*DeleteForeignDeviceTableEntry, error) {
 	d := &DeleteForeignDeviceTableEntry{}
-	d._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, d)
+	d._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	d.AddDebugContents(d, "bvlciAddress")
 	if d.GetRootMessage() == nil {
 		d.SetRootMessage(readWriteModel.NewBVLCDeleteForeignDeviceTableEntry(d.buildIPArgs()))
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DistributeBroadcastToNetwork.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DistributeBroadcastToNetwork.go
index 2ed4bcf..8b11300 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DistributeBroadcastToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_DistributeBroadcastToNetwork.go
@@ -35,9 +35,10 @@
 
 var _ BVLPDU = (*DistributeBroadcastToNetwork)(nil)
 
-func NewDistributeBroadcastToNetwork(args Args, kwArgs KWArgs) (*DistributeBroadcastToNetwork, error) {
+func NewDistributeBroadcastToNetwork(args Args, kwArgs KWArgs, options ...Option) (*DistributeBroadcastToNetwork, error) {
 	d := &DistributeBroadcastToNetwork{}
-	d._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, d)
+	d._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	switch npdu := d.GetRootMessage().(type) {
 	case readWriteModel.NPDU:
 		// Repackage
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ForwardedNPDU.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ForwardedNPDU.go
index 13c0b2a..b1fa112 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ForwardedNPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ForwardedNPDU.go
@@ -38,9 +38,11 @@
 
 var _ BVLPDU = (*ForwardedNPDU)(nil)
 
-func NewForwardedNPDU(addr *Address, args Args, kwArgs KWArgs) (*ForwardedNPDU, error) {
+// TODO: check this args desaster...
+func NewForwardedNPDU(addr *Address, args Args, kwArgs KWArgs, options ...Option) (*ForwardedNPDU, error) {
 	f := &ForwardedNPDU{}
-	f._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, f)
+	f._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	f.AddDebugContents(f, "bvlciAddress")
 	switch npdu := f.GetRootMessage().(type) {
 	case readWriteModel.NPDU:
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalBroadcastNPDU.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalBroadcastNPDU.go
index b9422c7..fd5f566 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalBroadcastNPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalBroadcastNPDU.go
@@ -35,9 +35,10 @@
 
 var _ BVLPDU = (*OriginalBroadcastNPDU)(nil)
 
-func NewOriginalBroadcastNPDU(args Args, kwArgs KWArgs) (*OriginalBroadcastNPDU, error) {
+func NewOriginalBroadcastNPDU(args Args, kwArgs KWArgs, options ...Option) (*OriginalBroadcastNPDU, error) {
 	o := &OriginalBroadcastNPDU{}
-	o._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, o)
+	o._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	switch npdu := o.GetRootMessage().(type) {
 	case readWriteModel.NPDU:
 		// Repackage
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalUnicastNPDU.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalUnicastNPDU.go
index 54f9669..60fa1a8 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalUnicastNPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_OriginalUnicastNPDU.go
@@ -38,9 +38,10 @@
 
 var _ BVLPDU = (*OriginalUnicastNPDU)(nil)
 
-func NewOriginalUnicastNPDU(args Args, kwArgs KWArgs) (*OriginalUnicastNPDU, error) {
+func NewOriginalUnicastNPDU(args Args, kwArgs KWArgs, options ...Option) (*OriginalUnicastNPDU, error) {
 	o := &OriginalUnicastNPDU{}
-	o._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, o)
+	o._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	switch npdu := o.GetRootMessage().(type) {
 	case readWriteModel.NPDU:
 		// Repackage
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTable.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTable.go
index 9ad3893..3643b1d 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTable.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTable.go
@@ -35,9 +35,10 @@
 
 var _ BVLPDU = (*ReadBroadcastDistributionTable)(nil)
 
-func NewReadBroadcastDistributionTable(args Args, kwArgs KWArgs) (*ReadBroadcastDistributionTable, error) {
+func NewReadBroadcastDistributionTable(args Args, kwArgs KWArgs, options ...Option) (*ReadBroadcastDistributionTable, error) {
 	r := &ReadBroadcastDistributionTable{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCReadBroadcastDistributionTable())
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTableAck.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTableAck.go
index 478b51a..b323021 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTableAck.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadBroadcastDistributionTableAck.go
@@ -38,9 +38,11 @@
 
 var _ BVLPDU = (*ReadBroadcastDistributionTableAck)(nil)
 
-func NewReadBroadcastDistributionTableAck(bdt []*Address, args Args, kwArgs KWArgs) (*ReadBroadcastDistributionTableAck, error) {
+// TODO: check this arg desaster
+func NewReadBroadcastDistributionTableAck(bdt []*Address, args Args, kwArgs KWArgs, options ...Option) (*ReadBroadcastDistributionTableAck, error) {
 	r := &ReadBroadcastDistributionTableAck{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	r.AddDebugContents(r, "bvlciBDT")
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCReadBroadcastDistributionTableAck(r.produceBroadcastDistributionTable()))
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTable.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTable.go
index 4e271ae..2456726 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTable.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTable.go
@@ -35,9 +35,10 @@
 
 var _ BVLPDU = (*ReadForeignDeviceTable)(nil)
 
-func NewReadForeignDeviceTable(args Args, kwArgs KWArgs) (*ReadForeignDeviceTable, error) {
+func NewReadForeignDeviceTable(args Args, kwArgs KWArgs, options ...Option) (*ReadForeignDeviceTable, error) {
 	r := &ReadForeignDeviceTable{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCReadForeignDeviceTable())
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTableAck.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTableAck.go
index 29c5668..a96c18d 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTableAck.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_ReadForeignDeviceTableAck.go
@@ -38,9 +38,11 @@
 
 var _ BVLPDU = (*ReadForeignDeviceTableAck)(nil)
 
-func NewReadForeignDeviceTableAck(fdt []*FDTEntry, args Args, kwArgs KWArgs) (*ReadForeignDeviceTableAck, error) {
+// TODO: check this arg desaster
+func NewReadForeignDeviceTableAck(fdt []*FDTEntry, args Args, kwArgs KWArgs, options ...Option) (*ReadForeignDeviceTableAck, error) {
 	r := &ReadForeignDeviceTableAck{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	r.AddDebugContents(r, "bvlciFDT++")
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCReadForeignDeviceTableAck(r.produceForeignDeviceTable()))
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_RegisterForeignDevice.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_RegisterForeignDevice.go
index 2b22a1a..74ce992 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_RegisterForeignDevice.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_RegisterForeignDevice.go
@@ -35,9 +35,11 @@
 
 var _ BVLPDU = (*RegisterForeignDevice)(nil)
 
-func NewRegisterForeignDevice(ttl *uint16, args Args, kwArgs KWArgs) (*RegisterForeignDevice, error) {
+// TODO: check this args desaster
+func NewRegisterForeignDevice(ttl *uint16, args Args, kwArgs KWArgs, options ...Option) (*RegisterForeignDevice, error) {
 	r := &RegisterForeignDevice{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCRegisterForeignDevice(r.bvlciTimeToLive))
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_Result.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_Result.go
index 964216e..0b4ff42 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_Result.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_Result.go
@@ -37,9 +37,11 @@
 
 var _ BVLPDU = (*Result)(nil)
 
-func NewResult(code *readWriteModel.BVLCResultCode, args Args, kwArgs KWArgs) (*Result, error) {
+// TODO: check this arg desaster...
+func NewResult(code *readWriteModel.BVLCResultCode, args Args, kwArgs KWArgs, options ...Option) (*Result, error) {
 	r := &Result{}
-	r._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, r)
+	r._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	if r.GetRootMessage() == nil {
 		r.SetRootMessage(readWriteModel.NewBVLCResult(r.bvlciResultCode))
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_WriteBroadcastDistributionTable.go b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_WriteBroadcastDistributionTable.go
index a42ca3f..3d45be9 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvll/bvll_WriteBroadcastDistributionTable.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvll/bvll_WriteBroadcastDistributionTable.go
@@ -38,9 +38,11 @@
 
 var _ BVLPDU = (*WriteBroadcastDistributionTable)(nil)
 
-func NewWriteBroadcastDistributionTable(bdt []*Address, args Args, kwArgs KWArgs) (*WriteBroadcastDistributionTable, error) {
+// TODO: check this arg desaster
+func NewWriteBroadcastDistributionTable(bdt []*Address, args Args, kwArgs KWArgs, options ...Option) (*WriteBroadcastDistributionTable, error) {
 	w := &WriteBroadcastDistributionTable{}
-	w._BVLPDU = NewBVLPDU(args, kwArgs).(*_BVLPDU)
+	options = AddLeafTypeIfAbundant(options, w)
+	w._BVLPDU = NewBVLPDU(args, kwArgs, options...).(*_BVLPDU)
 	w.AddDebugContents(w, "bvlciBDT")
 	if w.GetRootMessage() == nil {
 		w.SetRootMessage(readWriteModel.NewBVLCWriteBroadcastDistributionTable(w.produceBroadcastDistributionTable()))
diff --git a/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_BIPForeign.go b/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_BIPForeign.go
index 1515064..626b3ba 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_BIPForeign.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_BIPForeign.go
@@ -372,7 +372,7 @@
 // Immediately drops active foreign device registration and stops further
 // registration renewals.
 func (b *BIPForeign) Unregister() {
-	pdu := NewPDU(NoArgs, NKW(KWCompRootMessage, model.NewBVLCRegisterForeignDevice(0), KWCPCIDestination, b.bbmdAddress))
+	pdu := NewPDU(NoArgs, NKW(KWCPCIDestination, b.bbmdAddress), WithRootMessage(model.NewBVLCRegisterForeignDevice(0)))
 
 	// send it downstream
 	if err := b.Request(NA(pdu), NoKWArgs()); err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_UDPMultiplexer.go b/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_UDPMultiplexer.go
index c9e65f0..56c0cbb 100644
--- a/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_UDPMultiplexer.go
+++ b/plc4go/internal/bacnetip/bacgopes/bvllservice/bvllservice_UDPMultiplexer.go
@@ -197,7 +197,7 @@
 		return errors.New("invalid destination address type")
 	}
 
-	return m.directPort.Indication(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, pdu, KWCPCIDestination, dest))), NoKWArgs())
+	return m.directPort.Indication(NA(NewPDU(NoArgs, NKW(KWCPCIDestination, dest)), WithRootMessage(pdu)), NoKWArgs())
 }
 
 func (m *UDPMultiplexer) Confirmation(args Args, kwArgs KWArgs) error {
@@ -265,7 +265,7 @@
 
 	// TODO: we only support 0x81 at the moment
 	if m.AnnexJ != nil {
-		return m.AnnexJ.Response(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, pdu.GetRootMessage(), KWCPCISource, src, KWCPCIDestination, dest))), NoKWArgs())
+		return m.AnnexJ.Response(NA(NewPDU(NoArgs, NKW(KWCPCISource, src, KWCPCIDestination, dest)), WithRootMessage(pdu.GetRootMessage())), NoKWArgs())
 	}
 
 	return nil
diff --git a/plc4go/internal/bacnetip/bacgopes/comm/comm_PDU.go b/plc4go/internal/bacnetip/bacgopes/comm/comm_PDU.go
index be2adf1..c2c348a 100644
--- a/plc4go/internal/bacnetip/bacgopes/comm/comm_PDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/comm/comm_PDU.go
@@ -41,7 +41,7 @@
 	PDUData
 }
 
-func NewCPDU(data any, kwArgs KWArgs) CPDU {
+func NewCPDU(data any, kwArgs KWArgs, options ...Option) CPDU {
 	if _debug != nil {
 		_debug("__init__ %r %r", data, kwArgs)
 	}
@@ -62,9 +62,9 @@
 
 	// now continue on
 	p := &_PDU{
-		PCI: NewPCI(NoArgs, NKW(KWCPCIUserData, userData, KWCPCISource, source, destination, KWCPCIDestination, destination)),
+		PCI: NewPCI(NoArgs, NKW(KWCPCIUserData, userData, KWCPCISource, source, destination, KWCPCIDestination, destination), options...),
 	}
-	p.PDUData = NewPDUData(NA(data), kwArgs)
+	p.PDUData = NewPDUData(NA(data), kwArgs, options...)
 	return p
 }
 
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp.go b/plc4go/internal/bacnetip/bacgopes/comp/comp.go
index e3bd054..c1d2287 100644
--- a/plc4go/internal/bacnetip/bacgopes/comp/comp.go
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp.go
@@ -19,512 +19,7 @@
 
 package comp
 
-import (
-	"cmp"
-	"container/heap"
-	"fmt"
-	"iter"
-	"reflect"
-	"sort"
-	"strings"
-
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
-)
-
-type GenericFunction = func(args Args, kwArgs KWArgs) error
-
-type Arg any
-
-type Args []any
-
-var NoArgs = NewArgs()
-
-func NewArgs(args ...any) Args {
-	return args
-}
-
-// NA is a shortcut for NewArgs
-var NA = NewArgs
-
-// GetFromArgs gets a value fromArgs and if not present panics
-func GetFromArgs[T any](args Args, index int) T {
-	if index > len(args)-1 {
-		panic(fmt.Sprintf("index out of bounds: %d(len %d of %s)", index, len(args), args))
-	}
-	aAtI := args[index]
-	v, ok := aAtI.(T)
-	if !ok {
-		panic(fmt.Sprintf("argument #%d with type %T is not of type %T", index, aAtI, *new(T)))
-	}
-	return v
-}
-
-// GA is a shortcut for GetFromArgs
-func GA[T any](args Args, index int) T {
-	return GetFromArgs[T](args, index)
-}
-
-// GetFromArgsOptional gets a value from Args or return default if not present
-func GetFromArgsOptional[T any](args Args, index int, defaultValue T) (T, bool) {
-	if index > len(args)-1 {
-		return defaultValue, false
-	}
-	return args[index].(T), true
-}
-
-// GAO is a shortcut for GetFromArgsOptional
-func GAO[T any](args Args, index int, defaultValue T) (T, bool) {
-	return GetFromArgsOptional(args, index, defaultValue)
-}
-
-func (a Args) Format(s fmt.State, verb rune) {
-	switch verb {
-	case 'r':
-		_, _ = fmt.Fprintf(s, "(%s)", a.string(false, false)[1:len(a.string(false, false))-1])
-	case 's', 'v':
-		_, _ = fmt.Fprintf(s, "(%s)", a.String()[1:len(a.String())-1])
-	}
-}
-
-func (a Args) String() string {
-	return a.string(true, true)
-}
-func (a Args) string(printIndex bool, printType bool) string {
-	r := ""
-	for i, ea := range a {
-		eat := fmt.Sprintf("%T", ea)
-		switch tea := ea.(type) {
-		case []byte:
-			ea = Btox(tea, ".")
-		case string:
-			ea = "'" + tea + "'"
-		case fmt.Stringer:
-			if !IsNil(tea) {
-				teaString := tea.String()
-				ea = teaString
-				if strings.Contains(teaString, "\n") {
-					ea = "\n" + teaString + "\n"
-				}
-			}
-		}
-		if printIndex {
-			r += fmt.Sprintf("%d: ", i)
-		}
-		r += fmt.Sprintf("%v", ea)
-		if printType {
-			r += fmt.Sprintf(" (%s)", eat)
-		}
-		r += ", "
-	}
-	if r != "" {
-		r = r[:len(r)-2]
-	}
-	return "[" + r + "]"
-}
-
-type KWArgs map[KnownKey]any
-
-var NoKWArgs = NewKWArgs
-
-func NewKWArgs(kw ...any) KWArgs {
-	if len(kw)%2 != 0 {
-		panic("KWArgs must have an even number of arguments")
-	}
-	r := make(KWArgs)
-	for i := 0; i < len(kw)-1; i += 2 {
-		key, ok := kw[i].(KnownKey)
-		if !ok {
-			panic("keys must be of type KnownKey")
-		}
-		r[key] = kw[i+1]
-	}
-	return r
-}
-
-// NKW is a shortcut for NewKWArgs
-var NKW = NewKWArgs
-
-func (k KWArgs) Format(f fmt.State, verb rune) {
-	switch verb {
-	case 'r':
-		_, _ = fmt.Fprint(f, k.String())
-	}
-}
-
-func (k KWArgs) String() string {
-	r := ""
-	for kk, ea := range k {
-		switch kk {
-		case KWCompRootMessage:
-			// TODO: figure out if we want to control that for the %r above and do something different here
-			continue
-		}
-		switch tea := ea.(type) {
-		case []byte:
-			ea = Btox(tea, ".")
-		}
-		if IsNil(ea) {
-			ea = fmt.Sprintf("<nil>(%T)", ea)
-		}
-		r += fmt.Sprintf("'%s'=%v, ", kk, ea)
-	}
-	if r != "" {
-		r = r[:len(r)-2]
-	}
-	return "{" + r + "}"
-}
-
-// KW gets a value from KWArgs and if not present panics
-func KW[T any](kwArgs KWArgs, key KnownKey) T {
-	r, ok := kwArgs[key]
-	if !ok {
-		panic(fmt.Sprintf("key %v not found in kwArgs", key))
-	}
-	delete(kwArgs, key) // usually that means this argument was consumed so we get rid of it
-	return r.(T)
-}
-
-// KWO gets a value from KWArgs and if not present returns the supplied default value
-func KWO[T any](kwArgs KWArgs, key KnownKey, defaultValue T) (T, bool) {
-	r, ok := kwArgs[key]
-	if !ok {
-		return defaultValue, false
-	}
-	v, ok := r.(T)
-	if !ok {
-		return defaultValue, false
-	}
-	delete(kwArgs, key) // usually that means this argument was consumed so we get rid of it
-	return v, true
-}
-
-type KnownKey string
-
-const (
-	////
-	// General keys
-
-	KWAddActor   = KnownKey("addActor")
-	KWDelActor   = KnownKey("delActor")
-	KWActorError = KnownKey("actorError")
-	KWError      = KnownKey("error")
-
-	////
-	// comm.PCI related keys
-
-	KWCPCIUserData    = KnownKey("user_data")
-	KWCPCISource      = KnownKey("source")
-	KWCPCIDestination = KnownKey("destination")
-
-	////
-	// PCI related keys
-
-	KWPCIExpectingReply  = KnownKey("expecting_reply")
-	KWPCINetworkPriority = KnownKey("network_priority")
-
-	////
-	// NPDU related keys
-
-	KWWirtnNetwork           = KnownKey("wirtnNetwork")
-	KWIartnNetworkList       = KnownKey("iartnNetworkList")
-	KWIcbrtnNetwork          = KnownKey("icbrtnNetwork")
-	KWIcbrtnPerformanceIndex = KnownKey("icbrtnPerformanceIndex")
-	KWRmtnRejectionReason    = KnownKey("rmtnRejectionReason")
-	KWRmtnDNET               = KnownKey("rmtnDNET")
-	KWRbtnNetworkList        = KnownKey("rbtnNetworkList")
-	KWRatnNetworkList        = KnownKey("ratnNetworkList")
-	KWIrtTable               = KnownKey("irtTable")
-	KWIrtaTable              = KnownKey("irtaTable")
-	KWEctnDNET               = KnownKey("ectnDNET")
-	KWEctnTerminationTime    = KnownKey("ectnTerminationTime")
-	KWDctnDNET               = KnownKey("dctnDNET")
-	KWNniNet                 = KnownKey("nniNet")
-	KWNniFlag                = KnownKey("nniFlag")
-
-	////
-	// BVLL related keys
-
-	KWBvlciResultCode = KnownKey("bvlciResultCode")
-	KWBvlciBDT        = KnownKey("bvlciBDT")
-	KWBvlciAddress    = KnownKey("bvlciAddress")
-	KWFdAddress       = KnownKey("fdAddress")
-	KWFdTTL           = KnownKey("fdTTL")
-	KWFdRemain        = KnownKey("fdRemain")
-	KWBvlciTimeToLive = KnownKey("bvlciTimeToLive")
-	KWBvlciFDT        = KnownKey("bvlciFDT")
-
-	////
-	// APDU keys
-
-	KWConfirmedServiceChoice   = KnownKey("choice")
-	KWUnconfirmedServiceChoice = KnownKey("choice")
-	KWErrorClass               = KnownKey("errorClass")
-	KWErrorCode                = KnownKey("errorCode")
-	KWContext                  = KnownKey("context")
-	KWInvokedID                = KnownKey("invokeID")
-
-	////
-	// Compability layer keys
-
-	KWCompRootMessage = KnownKey("compRootMessage")
-	KWCompNLM         = KnownKey("compNLM")
-	KWCompAPDU        = KnownKey("compAPDU")
-)
-
 // Nothing give NoArgs and NoKWArgs()
 func Nothing() (Args, KWArgs) {
 	return NoArgs, NoKWArgs()
 }
-
-// An PriorityItem is something we manage in a priority queue.
-type PriorityItem[P cmp.Ordered, V any] struct {
-	Value    V // The value of the item; arbitrary.
-	Priority P // The priority of the item in the queue.
-	// The Index is needed by update and is maintained by the heap.Interface methods.
-	Index int // The Index of the item in the heap.
-}
-
-func (p *PriorityItem[P, V]) String() string {
-	v := fmt.Sprintf("%v", p.Value)
-	if strings.Contains(v, "\n") {
-		v = "\n" + v + "\n"
-	}
-	return fmt.Sprintf("[%v: prio %v - value %s], ", p.Index, p.Priority, v)
-}
-
-// GA PriorityQueue implements heap.Interface and holds Items.
-type PriorityQueue[P cmp.Ordered, V any] []*PriorityItem[P, V]
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq PriorityQueue[P, V]) Len() int { return len(pq) }
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq PriorityQueue[P, V]) Less(i, j int) bool {
-	return cmp.Less((pq)[i].Priority, (pq)[j].Priority)
-}
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq PriorityQueue[P, V]) Swap(i, j int) {
-	(pq)[i], (pq)[j] = (pq)[j], (pq)[i]
-	(pq)[i].Index = i
-	(pq)[j].Index = j
-}
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq *PriorityQueue[P, V]) Push(x any) {
-	n := len(*pq)
-	item := x.(*PriorityItem[P, V])
-	item.Index = n
-	*pq = append(*pq, item)
-}
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq *PriorityQueue[P, V]) Pop() any {
-	old := *pq
-	n := len(old)
-	item := old[n-1]
-	old[n-1] = nil  // avoid memory leak
-	item.Index = -1 // for safety
-	*pq = old[0 : n-1]
-	return item
-}
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq *PriorityQueue[P, V]) Clear() {
-	if pq == nil {
-		return
-	}
-	*pq = PriorityQueue[P, V]{}
-}
-
-// update modifies the priority and value of an Item in the queue.
-//
-//goland:noinspection GoMixedReceiverTypes
-func (pq *PriorityQueue[P, V]) update(item *PriorityItem[P, V], value V, priority P) {
-	item.Value = value
-	item.Priority = priority
-	heap.Fix(pq, item.Index)
-}
-
-//goland:noinspection GoMixedReceiverTypes
-func (pq PriorityQueue[P, V]) String() string {
-	var buf strings.Builder
-	for _, p := range pq {
-		buf.WriteString(p.String())
-	}
-	s := buf.String()
-	if s == "" {
-		return ""
-	}
-	if strings.Contains(s, "\n") {
-		s = "\n" + s + "\n"
-	}
-	var p P
-	var v V
-	return fmt.Sprintf("PriorityQueue[%T,%T]{%s}", p, v, s[:len(s)-2])
-}
-
-// NillableKey is a key which can be used in maps
-type NillableKey[T any] struct {
-	Value T
-	IsNil bool
-}
-
-func (n NillableKey[T]) String() string {
-	if n.IsNil {
-		return "nil"
-	}
-	return fmt.Sprintf("%v", n.Value)
-}
-
-// NK creates a new NillableKey of type K
-func NK[T any, K NillableKey[T]](value *T) K {
-	var _nk NillableKey[T]
-	if value == nil {
-		_nk.IsNil = true
-		return K(_nk)
-	}
-	_nk.Value = *value
-	return K(_nk)
-}
-
-type Comparable interface {
-	Equals(other any) bool
-}
-
-type Copyable interface {
-	DeepCopy() any
-}
-
-// DeepCopy copies things implementing Copyable
-func DeepCopy[T Copyable](copyable Copyable) T {
-	return copyable.DeepCopy().(T)
-}
-
-// CopyPtr copies things that are a pointer to something
-func CopyPtr[T any](t *T) *T {
-	if t == nil {
-		return nil
-	}
-	tc := *t
-	return &tc
-}
-
-type Updater interface {
-	Update(Arg) error
-}
-
-type Encoder interface {
-	Encode(Arg) error
-}
-
-type Decoder interface {
-	Decode(Arg) error
-}
-
-// OptionalOption allows options to be applied that might be optional
-func OptionalOption[V any, T any](value *V, opt func(V) func(*T)) func(*T) {
-	if value != nil {
-		return opt(*value)
-	}
-	return func(c *T) {}
-}
-
-// OptionalOption2 allows options to be applied that might be optional
-func OptionalOption2[V1 any, V2 any, T any](value1 *V1, value2 *V2, opt func(V1, V2) func(*T)) func(*T) {
-	v1Set := value1 != nil
-	v2Set := value2 != nil
-	if (v1Set && !v2Set) || (!v1Set && v2Set) {
-		return func(c *T) {}
-	}
-	if v1Set {
-		return opt(*value1, *value2)
-	}
-	return func(c *T) {}
-}
-
-type MissingRequiredParameter struct {
-	Message string
-}
-
-func (m MissingRequiredParameter) Error() string {
-	return m.Message
-}
-
-// SortedMapIterator lets you iterate over an array in a deterministic way
-func SortedMapIterator[K cmp.Ordered, V any](m map[K]V) iter.Seq2[K, V] {
-	keys := make([]K, len(m))
-	i := 0
-	for k := range m {
-		keys[i] = k
-		i++
-	}
-	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
-	return func(yield func(K, V) bool) {
-		for _, k := range keys {
-			if !yield(k, m[k]) {
-				return
-			}
-		}
-	}
-}
-
-// OR returns a or b
-func OR[T comparable](a T, b T) T {
-	if reflect.ValueOf(a).IsNil() || (reflect.ValueOf(a).Kind() == reflect.Ptr && reflect.ValueOf(a).IsNil()) { // TODO: check if there is another way than using reflect
-		return b
-	} else {
-		return a
-	}
-}
-
-// ToPtr gives a Ptr
-func ToPtr[T any](value T) *T {
-	return &value
-}
-
-// Try something and return panic as error
-func Try(f func() error) (err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			err = fmt.Errorf("panic: %v", r)
-		}
-	}()
-	return f()
-}
-
-// Try1 something and return panic as error
-func Try1[T any](f func() (T, error)) (v T, err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			err = fmt.Errorf("panic: %v", r)
-		}
-	}()
-	return f()
-}
-
-// IsNil when nil checks aren't enough
-func IsNil(v interface{}) bool {
-	if v == nil {
-		return true
-	}
-	valueOf := reflect.ValueOf(v)
-	switch valueOf.Kind() {
-	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
-		return valueOf.IsNil()
-	default:
-		return false
-	}
-}
-
-func ToStringers[I any](in []I) []fmt.Stringer {
-	return ConvertSlice[I, fmt.Stringer](in)
-}
-
-func ConvertSlice[I any, O any](in []I) (out []O) {
-	out = make([]O, len(in))
-	for i, v := range in {
-		out[i] = any(v).(O)
-	}
-	return
-}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_Args.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_Args.go
new file mode 100644
index 0000000..f05bc76
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_Args.go
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"fmt"
+	"strings"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
+)
+
+type Arg any
+
+type Args []any
+
+var NoArgs = NewArgs()
+
+func NewArgs(args ...any) Args {
+	return args
+}
+
+// NA is a shortcut for NewArgs
+var NA = NewArgs
+
+// GetFromArgs gets a value fromArgs and if not present panics
+func GetFromArgs[T any](args Args, index int) T {
+	if index > len(args)-1 {
+		panic(fmt.Sprintf("index out of bounds: %d(len %d of %s)", index, len(args), args))
+	}
+	aAtI := args[index]
+	v, ok := aAtI.(T)
+	if !ok {
+		panic(fmt.Sprintf("argument #%d with type %T is not of type %T", index, aAtI, *new(T)))
+	}
+	return v
+}
+
+// GA is a shortcut for GetFromArgs
+func GA[T any](args Args, index int) T {
+	return GetFromArgs[T](args, index)
+}
+
+// GetFromArgsOptional gets a value from Args or return default if not present
+func GetFromArgsOptional[T any](args Args, index int, defaultValue T) (T, bool) {
+	if index > len(args)-1 {
+		return defaultValue, false
+	}
+	return args[index].(T), true
+}
+
+// GAO is a shortcut for GetFromArgsOptional
+func GAO[T any](args Args, index int, defaultValue T) (T, bool) {
+	return GetFromArgsOptional(args, index, defaultValue)
+}
+
+func (a Args) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 'r':
+		_, _ = fmt.Fprintf(s, "(%s)", a.string(false, false)[1:len(a.string(false, false))-1])
+	case 's', 'v':
+		_, _ = fmt.Fprintf(s, "(%s)", a.String()[1:len(a.String())-1])
+	}
+}
+
+func (a Args) String() string {
+	return a.string(true, true)
+}
+func (a Args) string(printIndex bool, printType bool) string {
+	r := ""
+	for i, ea := range a {
+		eat := fmt.Sprintf("%T", ea)
+		switch tea := ea.(type) {
+		case []byte:
+			ea = Btox(tea, ".")
+		case string:
+			ea = "'" + tea + "'"
+		case fmt.Stringer:
+			if !IsNil(tea) {
+				teaString := tea.String()
+				ea = teaString
+				if strings.Contains(teaString, "\n") {
+					ea = "\n" + teaString + "\n"
+				}
+			}
+		}
+		if printIndex {
+			r += fmt.Sprintf("%d: ", i)
+		}
+		r += fmt.Sprintf("%v", ea)
+		if printType {
+			r += fmt.Sprintf(" (%s)", eat)
+		}
+		r += ", "
+	}
+	if r != "" {
+		r = r[:len(r)-2]
+	}
+	return "[" + r + "]"
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_KWArgs.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_KWArgs.go
new file mode 100644
index 0000000..1dacdc3
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_KWArgs.go
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"fmt"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
+)
+
+type KnownKey string
+
+type KWArgs map[KnownKey]any
+
+var NoKWArgs = NewKWArgs
+
+func NewKWArgs(kw ...any) KWArgs {
+	if len(kw)%2 != 0 {
+		panic("KWArgs must have an even number of arguments")
+	}
+	r := make(KWArgs)
+	for i := 0; i < len(kw)-1; i += 2 {
+		key, ok := kw[i].(KnownKey)
+		if !ok {
+			panic("keys must be of type KnownKey")
+		}
+		r[key] = kw[i+1]
+	}
+	return r
+}
+
+// NKW is a shortcut for NewKWArgs
+var NKW = NewKWArgs
+
+func (k KWArgs) Format(f fmt.State, verb rune) {
+	switch verb {
+	case 'r':
+		_, _ = fmt.Fprint(f, k.String())
+	}
+}
+
+func (k KWArgs) String() string {
+	r := ""
+	for kk, ea := range k {
+		switch tea := ea.(type) {
+		case []byte:
+			ea = Btox(tea, ".")
+		}
+		if IsNil(ea) {
+			ea = fmt.Sprintf("<nil>(%T)", ea)
+		}
+		r += fmt.Sprintf("'%s'=%v, ", kk, ea)
+	}
+	if r != "" {
+		r = r[:len(r)-2]
+	}
+	return "{" + r + "}"
+}
+
+// KW gets a value from KWArgs and if not present panics
+func KW[T any](kwArgs KWArgs, key KnownKey) T {
+	r, ok := kwArgs[key]
+	if !ok {
+		panic(fmt.Sprintf("key %v not found in kwArgs", key))
+	}
+	delete(kwArgs, key) // usually that means this argument was consumed so we get rid of it
+	return r.(T)
+}
+
+// KWO gets a value from KWArgs and if not present returns the supplied default value
+func KWO[T any](kwArgs KWArgs, key KnownKey, defaultValue T) (T, bool) {
+	r, ok := kwArgs[key]
+	if !ok {
+		return defaultValue, false
+	}
+	v, ok := r.(T)
+	if !ok {
+		return defaultValue, false
+	}
+	delete(kwArgs, key) // usually that means this argument was consumed so we get rid of it
+	return v, true
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_KnownKeys.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_KnownKeys.go
new file mode 100644
index 0000000..12f740c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_KnownKeys.go
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+const (
+	////
+	// General keys
+
+	KWAddActor   = KnownKey("addActor")
+	KWDelActor   = KnownKey("delActor")
+	KWActorError = KnownKey("actorError")
+	KWError      = KnownKey("error")
+
+	////
+	// comm.PCI related keys
+
+	KWCPCIUserData    = KnownKey("user_data")
+	KWCPCISource      = KnownKey("source")
+	KWCPCIDestination = KnownKey("destination")
+
+	////
+	// PCI related keys
+
+	KWPCIExpectingReply  = KnownKey("expecting_reply")
+	KWPCINetworkPriority = KnownKey("network_priority")
+
+	////
+	// NPDU related keys
+
+	KWWirtnNetwork           = KnownKey("wirtnNetwork")
+	KWIartnNetworkList       = KnownKey("iartnNetworkList")
+	KWIcbrtnNetwork          = KnownKey("icbrtnNetwork")
+	KWIcbrtnPerformanceIndex = KnownKey("icbrtnPerformanceIndex")
+	KWRmtnRejectionReason    = KnownKey("rmtnRejectionReason")
+	KWRmtnDNET               = KnownKey("rmtnDNET")
+	KWRbtnNetworkList        = KnownKey("rbtnNetworkList")
+	KWRatnNetworkList        = KnownKey("ratnNetworkList")
+	KWIrtTable               = KnownKey("irtTable")
+	KWIrtaTable              = KnownKey("irtaTable")
+	KWEctnDNET               = KnownKey("ectnDNET")
+	KWEctnTerminationTime    = KnownKey("ectnTerminationTime")
+	KWDctnDNET               = KnownKey("dctnDNET")
+	KWNniNet                 = KnownKey("nniNet")
+	KWNniFlag                = KnownKey("nniFlag")
+
+	////
+	// BVLL related keys
+
+	KWBvlciResultCode = KnownKey("bvlciResultCode")
+	KWBvlciBDT        = KnownKey("bvlciBDT")
+	KWBvlciAddress    = KnownKey("bvlciAddress")
+	KWFdAddress       = KnownKey("fdAddress")
+	KWFdTTL           = KnownKey("fdTTL")
+	KWFdRemain        = KnownKey("fdRemain")
+	KWBvlciTimeToLive = KnownKey("bvlciTimeToLive")
+	KWBvlciFDT        = KnownKey("bvlciFDT")
+
+	////
+	// APDU keys
+
+	KWConfirmedServiceChoice   = KnownKey("choice")
+	KWUnconfirmedServiceChoice = KnownKey("choice")
+	KWErrorClass               = KnownKey("errorClass")
+	KWErrorCode                = KnownKey("errorCode")
+	KWContext                  = KnownKey("context")
+	KWInvokedID                = KnownKey("invokeID")
+
+	////
+	// Object keys
+
+	KWObjectName                = KnownKey("objectName")
+	KWObjectIdentifier          = KnownKey("objectIdentifier")
+	KWMaximumApduLengthAccepted = KnownKey("maximumApduLengthAccepted")
+	KWSegmentationSupported     = KnownKey("segmentationSupported")
+	KWMaxSegmentsAccepted       = KnownKey("segmentsAccepted")
+	KWNumberOfAPDURetries       = KnownKey("numberOfAPDURetries")
+	KWVendorIdentifier          = KnownKey("vendorIdentifier")
+)
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_PriorityQueue.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_PriorityQueue.go
new file mode 100644
index 0000000..18afca4
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_PriorityQueue.go
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"cmp"
+	"container/heap"
+	"fmt"
+	"strings"
+)
+
+// An PriorityItem is something we manage in a priority queue.
+type PriorityItem[P cmp.Ordered, V any] struct {
+	Value    V // The value of the item; arbitrary.
+	Priority P // The priority of the item in the queue.
+	// The Index is needed by update and is maintained by the heap.Interface methods.
+	Index int // The Index of the item in the heap.
+}
+
+func (p *PriorityItem[P, V]) String() string {
+	v := fmt.Sprintf("%v", p.Value)
+	if strings.Contains(v, "\n") {
+		v = "\n" + v + "\n"
+	}
+	return fmt.Sprintf("[%v: prio %v - value %s], ", p.Index, p.Priority, v)
+}
+
+// GA PriorityQueue implements heap.Interface and holds Items.
+type PriorityQueue[P cmp.Ordered, V any] []*PriorityItem[P, V]
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq PriorityQueue[P, V]) Len() int { return len(pq) }
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq PriorityQueue[P, V]) Less(i, j int) bool {
+	return cmp.Less((pq)[i].Priority, (pq)[j].Priority)
+}
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq PriorityQueue[P, V]) Swap(i, j int) {
+	(pq)[i], (pq)[j] = (pq)[j], (pq)[i]
+	(pq)[i].Index = i
+	(pq)[j].Index = j
+}
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq *PriorityQueue[P, V]) Push(x any) {
+	n := len(*pq)
+	item := x.(*PriorityItem[P, V])
+	item.Index = n
+	*pq = append(*pq, item)
+}
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq *PriorityQueue[P, V]) Pop() any {
+	old := *pq
+	n := len(old)
+	item := old[n-1]
+	old[n-1] = nil  // avoid memory leak
+	item.Index = -1 // for safety
+	*pq = old[0 : n-1]
+	return item
+}
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq *PriorityQueue[P, V]) Clear() {
+	if pq == nil {
+		return
+	}
+	*pq = PriorityQueue[P, V]{}
+}
+
+// update modifies the priority and value of an Item in the queue.
+//
+//goland:noinspection GoMixedReceiverTypes
+func (pq *PriorityQueue[P, V]) update(item *PriorityItem[P, V], value V, priority P) {
+	item.Value = value
+	item.Priority = priority
+	heap.Fix(pq, item.Index)
+}
+
+//goland:noinspection GoMixedReceiverTypes
+func (pq PriorityQueue[P, V]) String() string {
+	var buf strings.Builder
+	for _, p := range pq {
+		buf.WriteString(p.String())
+	}
+	s := buf.String()
+	if s == "" {
+		return ""
+	}
+	if strings.Contains(s, "\n") {
+		s = "\n" + s + "\n"
+	}
+	var p P
+	var v V
+	return fmt.Sprintf("PriorityQueue[%T,%T]{%s}", p, v, s[:len(s)-2])
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_commons.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_commons.go
new file mode 100644
index 0000000..3d5062d
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_commons.go
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"cmp"
+	"fmt"
+	"iter"
+	"reflect"
+	"sort"
+)
+
+// NillableKey is a key which can be used in maps
+type NillableKey[T any] struct {
+	Value T
+	IsNil bool
+}
+
+func (n NillableKey[T]) String() string {
+	if n.IsNil {
+		return "nil"
+	}
+	return fmt.Sprintf("%v", n.Value)
+}
+
+// NK creates a new NillableKey of type K
+func NK[T any, K NillableKey[T]](value *T) K {
+	var _nk NillableKey[T]
+	if value == nil {
+		_nk.IsNil = true
+		return K(_nk)
+	}
+	_nk.Value = *value
+	return K(_nk)
+}
+
+// DeepCopy copies things implementing Copyable
+func DeepCopy[T Copyable](copyable Copyable) T {
+	return copyable.DeepCopy().(T)
+}
+
+// CopyPtr copies things that are a pointer to something
+func CopyPtr[T any](t *T) *T {
+	if t == nil {
+		return nil
+	}
+	tc := *t
+	return &tc
+}
+
+// SortedMapIterator lets you iterate over an array in a deterministic way
+func SortedMapIterator[K cmp.Ordered, V any](m map[K]V) iter.Seq2[K, V] {
+	keys := make([]K, len(m))
+	i := 0
+	for k := range m {
+		keys[i] = k
+		i++
+	}
+	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
+	return func(yield func(K, V) bool) {
+		for _, k := range keys {
+			if !yield(k, m[k]) {
+				return
+			}
+		}
+	}
+}
+
+// OR returns a or b
+func OR[T comparable](a T, b T) T {
+	if reflect.ValueOf(a).IsNil() || (reflect.ValueOf(a).Kind() == reflect.Ptr && reflect.ValueOf(a).IsNil()) { // TODO: check if there is another way than using reflect
+		return b
+	} else {
+		return a
+	}
+}
+
+// ToPtr gives a Ptr
+func ToPtr[T any](value T) *T {
+	return &value
+}
+
+// Try something and return panic as error
+func Try(f func() error) (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("panic: %v", r)
+		}
+	}()
+	return f()
+}
+
+// Try1 something and return panic as error
+func Try1[T any](f func() (T, error)) (v T, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("panic: %v", r)
+		}
+	}()
+	return f()
+}
+
+// IsNil when nil checks aren't enough
+func IsNil(v interface{}) bool {
+	if v == nil {
+		return true
+	}
+	valueOf := reflect.ValueOf(v)
+	switch valueOf.Kind() {
+	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
+		return valueOf.IsNil()
+	default:
+		return false
+	}
+}
+
+func ToStringers[I any](in []I) []fmt.Stringer {
+	return ConvertSlice[I, fmt.Stringer](in)
+}
+
+func ConvertSlice[I any, O any](in []I) (out []O) {
+	out = make([]O, len(in))
+	for i, v := range in {
+		out[i] = any(v).(O)
+	}
+	return
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_errors.go
similarity index 65%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/comp/comp_errors.go
index efbea52..627701f 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_errors.go
@@ -17,19 +17,12 @@
  * under the License.
  */
 
-package object
+package comp
 
-import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
-
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
+type MissingRequiredParameter struct {
+	Message string
 }
 
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+func (m MissingRequiredParameter) Error() string {
+	return m.Message
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance.go
new file mode 100644
index 0000000..9823acb
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance.go
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+)
+
+var inheritanceDebug = func(_ string, _ ...interface{}) {}
+
+// GenericConstructor is the generic signature for constructors
+type GenericConstructor[T any] func(args Args, kwArgs KWArgs, options ...Option) (*T, error)
+
+type leafType struct {
+	defaultOption
+
+	name string
+}
+
+// AddLeafTypeIfAbundant can be used to add a leaf type if not already set
+func AddLeafTypeIfAbundant[T any](options []Option, leaf *T) []Option {
+	for _, option := range options {
+		switch option.(type) {
+		case genericOption[T]:
+			// We have a match so nothing to do
+			return options
+		}
+	}
+	return append(options, WithLeafType(leaf))
+}
+
+// WithLeafType can be used to add a leaf type
+func WithLeafType[T any](leaf *T) Option {
+	return leafType{name: fmt.Sprintf("%T", leaf)[1:]}
+}
+
+// ExtractLeafName or return default
+func ExtractLeafName(options []Option, defaultName string) string {
+	for _, option := range options {
+		switch option := option.(type) {
+		case leafType:
+			return option.name
+		}
+	}
+	return defaultName
+}
+
+// sharedHolder holds a common super
+type sharedHolder[T any] struct {
+	defaultOption
+	commonSuper *T
+}
+
+// sharedHolders is a collection of different holders (useful if you don't want to define every super in the tree)
+type sharedHolders struct {
+	defaultOption
+	holders map[any]struct{}
+}
+
+// AddMultiInheritanceSupportIfAbundant adds a WithMultiInheritanceSupport if abundant
+func AddMultiInheritanceSupportIfAbundant(options []Option) []Option {
+	for _, option := range options {
+		switch option.(type) {
+		case *sharedHolders:
+			inheritanceDebug("*sharedHolders found on add. address: %p", option)
+			// We have a match so nothing to do
+			return options
+		}
+	}
+	option := WithMultiInheritanceSupport()
+	inheritanceDebug("add new *sharedHolders on add. address: %p", option)
+	return append(options, option)
+}
+
+// WithMultiInheritanceSupport is a quick way to ensure that multi inheritance is respected from a root node.
+func WithMultiInheritanceSupport() Option {
+	return &sharedHolders{holders: map[any]struct{}{}}
+}
+
+// AddSharedSuperIfAbundant adds a WithSharedSuper if abundant
+func AddSharedSuperIfAbundant[T any](options []Option) []Option {
+	for _, option := range options {
+		switch option := option.(type) {
+		case *sharedHolder[T]:
+			inheritanceDebug("*sharedHolder found on add. address: %p", option)
+			// We have a match so nothing to do
+			return options
+		case *sharedHolders:
+			for option := range option.holders {
+				switch option := option.(type) {
+				case *sharedHolder[T]:
+					inheritanceDebug("*sharedHolder found in holders on add. address: %p", option)
+					// We have a match so nothing to do
+					return options
+				}
+			}
+		}
+	}
+	option := WithSharedSuper[T]()
+	inheritanceDebug("add new *sharedHolder on add. address: %p", option)
+	return append(options, option)
+}
+
+// WithSharedSuper adds a shared super holder. Useful in multi-inheritance
+func WithSharedSuper[T any]() Option {
+	return &sharedHolder[T]{}
+}
+
+// CreateSharedSuperIfAbundant is the actual factory/retrieval function used when the actual object is about to be build
+func CreateSharedSuperIfAbundant[T any](options []Option, constructor GenericConstructor[T], cArgs Args, ckwArgs KWArgs, cOptions ...Option) (*T, error) {
+	var holders *sharedHolders
+	// look for shared holders containers so we can add it when we find one
+sharedHoldersScan:
+	for _, option := range options {
+		switch option := option.(type) {
+		case *sharedHolders:
+			holders = option
+			inheritanceDebug("*sharedHolders found. address: %p", option)
+			// check if we have an instance in there
+			for holder := range option.holders {
+				if option, ok := holder.(*sharedHolder[T]); ok {
+					inheritanceDebug("found *sharedHolder[T]. address: %p", option)
+					for _, existingOption := range options {
+						if existingOption == option {
+							inheritanceDebug("already there. address: %p", option)
+							break sharedHoldersScan // we are good, no need to add
+						}
+					}
+					inheritanceDebug("appending it. address: %p", option)
+					options = append(options, option) // Append it to the options and let the code below do its magic
+					break sharedHoldersScan           // we are good, no need to add
+				}
+			}
+			// We haven't found on so we just add an empty one
+			holder := new(sharedHolder[T])
+			inheritanceDebug("adding a new holder. address: %p", holder)
+			options = append(options, holder)
+			break sharedHoldersScan // we are good, no need to add
+		}
+	}
+	// look for shared holders
+	for _, option := range options {
+		switch option := option.(type) {
+		case *sharedHolder[T]:
+			inheritanceDebug("*sharedHolder found. address: %p", option)
+			if holders != nil { // Add it to a holder instance if there are some
+				inheritanceDebug("adding it to holders. address: %p", holders)
+				holders.holders[option] = struct{}{}
+			}
+			commonSuper := option.commonSuper
+			if commonSuper == nil {
+				// Apparently it is not initialized so we do that now
+				var err error
+				commonSuper, err = constructor(cArgs, ckwArgs, cOptions...)
+				if err != nil {
+					return nil, errors.Wrap(err, "error creating object")
+				}
+				inheritanceDebug("new common super. address: %p (%[1]T)", commonSuper)
+				option.commonSuper = commonSuper
+			} else {
+				inheritanceDebug("existing common super. address: %p (%[1]T)", commonSuper)
+			}
+			return commonSuper, nil
+		}
+	}
+	inheritanceDebug("No holder, just fallback")
+	// we don't share anything, so just create one
+	commonSuper, err := constructor(cArgs, ckwArgs, cOptions...)
+	inheritanceDebug("new common super fallback. address: %p (%[1]T)", commonSuper)
+	return commonSuper, err
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance_test.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance_test.go
new file mode 100644
index 0000000..75625d3
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_inheritance_test.go
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"math/rand"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestSuperSharing(t *testing.T) {
+	inheritanceDebug = t.Logf
+	type A struct{ int }
+	type B struct{ *A }
+	type C struct{ *A }
+	type D struct{ *A }
+	type E struct {
+		*D
+	}
+	type F struct {
+		*B
+		*C
+		*D
+		*E
+	}
+	// D has B and C and B and C share A
+	newA := func(args Args, kwArgs KWArgs, options ...Option) (*A, error) {
+		t.Log("building A")
+		return &A{rand.Int()}, nil
+	}
+	newB := func(args Args, kwArgs KWArgs, options ...Option) (*B, error) {
+		t.Log("building B")
+		b := &B{}
+		var err error
+		b.A, err = CreateSharedSuperIfAbundant(options, newA, args, kwArgs, options...)
+		require.NoError(t, err)
+		return b, nil
+	}
+	newC := func(args Args, kwArgs KWArgs, options ...Option) (*C, error) {
+		t.Log("building C")
+		c := &C{}
+		var err error
+		c.A, err = CreateSharedSuperIfAbundant(options, newA, args, kwArgs, options...)
+		require.NoError(t, err)
+		return c, nil
+	}
+	newD := func(args Args, kwArgs KWArgs, options ...Option) (*D, error) {
+		t.Log("building D")
+		d := &D{}
+		options = AddSharedSuperIfAbundant[A](options) // enrich
+		var err error
+		d.A, err = CreateSharedSuperIfAbundant(options, newA, args, kwArgs, options...)
+		require.NoError(t, err)
+		return d, nil
+	}
+	newE := func(args Args, kwArgs KWArgs, _ ...Option) (*E, error) {
+		t.Log("building E")
+		e := &E{}
+		options := []Option{WithSharedSuper[A]()} // replace
+		var err error
+		e.D, err = newD(args, kwArgs, options...)
+		require.NoError(t, err)
+		return e, nil
+	}
+	newF := func(args Args, kwArgs KWArgs, options ...Option) (*F, error) {
+		t.Log("building F")
+		f := &F{}
+		if len(options) == 0 {
+			options = []Option{WithSharedSuper[A]()}
+		}
+		var err error
+		f.B, err = newB(args, kwArgs, options...)
+		require.NoError(t, err)
+		f.C, err = newC(args, kwArgs, options...)
+		require.NoError(t, err)
+		f.D, err = newD(args, kwArgs, options...)
+		require.NoError(t, err)
+		f.E, err = newE(args, kwArgs, options...)
+		require.NoError(t, err)
+		return f, nil
+	}
+	t.Run("only set the option for F", func(t *testing.T) {
+		inheritanceDebug = t.Logf
+		f, err := newF(NoArgs, NoKWArgs())
+		require.NoError(t, err)
+		require.NotNil(t, f)
+		ba := f.B.A
+		ca := f.C.A
+		da := f.D.A
+		ea := f.E.A
+		assert.Same(t, ba, ca)
+		assert.Same(t, ba, da)
+		assert.NotSame(t, ba, ea) // This is not the same
+		assert.NotSame(t, da, ea) // This is not the same as e replaces all options on purpose
+		assert.Same(t, ba, ca)
+	})
+	t.Run("use catch em all approach", func(t *testing.T) {
+		f, err := newF(NoArgs, NoKWArgs(), WithMultiInheritanceSupport())
+		require.NoError(t, err)
+		require.NotNil(t, f)
+		t.Logf("f\t\t%p", f)
+		t.Logf("f.b\t%p", f.B)
+		ba := f.B.A
+		t.Logf("f.b.a\t%p", ba)
+		t.Logf("f.c\t%p", f.C)
+		ca := f.C.A
+		t.Logf("f.c.a\t%p", ca)
+		t.Logf("f.d\t%p", f.D)
+		da := f.D.A
+		t.Logf("f.d.a\t%p", da)
+		t.Logf("f.e\t%p", f.E)
+		ea := f.E.A
+		t.Logf("f.e.a\t%p", ea)
+		assert.Same(t, ba, ca)
+		assert.Same(t, ba, da)
+		assert.NotSame(t, ba, ea) // This is not the same
+		assert.NotSame(t, da, ea) // This is not the same as e replaces all options on purpose
+		assert.Same(t, ba, ca)
+	})
+	t.Run("use catch em all approach With addition", func(t *testing.T) {
+		var options []Option
+		options = AddMultiInheritanceSupportIfAbundant(options)
+		f, err := newF(NoArgs, NoKWArgs(), options...)
+		require.NoError(t, err)
+		require.NotNil(t, f)
+		ba := f.B.A
+		ca := f.C.A
+		da := f.D.A
+		ea := f.E.A
+		assert.Same(t, ba, ca)
+		assert.Same(t, ba, da)
+		assert.NotSame(t, ba, ea) // This is not the same
+		assert.NotSame(t, da, ea) // This is not the same as e replaces all options on purpose
+		assert.Same(t, ba, ca)
+	})
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_interfaces.go
similarity index 66%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/comp/comp_interfaces.go
index efbea52..1254b2d 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_interfaces.go
@@ -17,19 +17,26 @@
  * under the License.
  */
 
-package object
+package comp
 
-import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+type GenericFunction = func(args Args, kwArgs KWArgs) error
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
+type Updater interface {
+	Update(Arg) error
 }
 
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
+type Encoder interface {
+	Encode(Arg) error
 }
 
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+type Decoder interface {
+	Decode(Arg) error
+}
+
+type Comparable interface {
+	Equals(other any) bool
+}
+
+type Copyable interface {
+	DeepCopy() any
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_options.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_options.go
new file mode 100644
index 0000000..e19f463
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_options.go
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+// OptionalOption allows options to be applied that might be optional
+func OptionalOption[V any, T any](value *V, opt func(V) func(*T)) func(*T) {
+	if value != nil {
+		return opt(*value)
+	}
+	return func(c *T) {}
+}
+
+// OptionalOption2 allows options to be applied that might be optional
+func OptionalOption2[V1 any, V2 any, T any](value1 *V1, value2 *V2, opt func(V1, V2) func(*T)) func(*T) {
+	v1Set := value1 != nil
+	v2Set := value2 != nil
+	if (v1Set && !v2Set) || (!v1Set && v2Set) {
+		return func(c *T) {}
+	}
+	if v1Set {
+		return opt(*value1, *value2)
+	}
+	return func(c *T) {}
+}
+
+// Option is a generic interface for transporting options which are meant to bubble up
+type Option interface {
+	isOption()
+}
+
+type defaultOption struct {
+}
+
+func (defaultOption) isOption() {}
+
+// Combine Option s with different Option s
+func Combine(options []Option, additionalOptions ...Option) []Option {
+	return append(options, additionalOptions...)
+}
+
+type genericOption[T any] struct {
+	defaultOption
+	value T
+}
+
+// AsOption converts a value T as option
+func AsOption[T any](value T) Option {
+	return genericOption[T]{value: value}
+}
+
+// GenericApplier wraps a func(T) as option
+type GenericApplier[T any] genericOption[func(T)]
+
+// WrapGenericApplier is a factory function for GenericApplier
+func WrapGenericApplier[T any](applier func(T)) GenericApplier[T] {
+	return GenericApplier[T]{value: applier}
+}
+
+// ApplyAppliers applies all appliers to target if genericOption matches GenericApplier
+func ApplyAppliers[T any](options []Option, target T) {
+	for _, option := range options {
+		switch option := option.(type) {
+		case GenericApplier[T]:
+			option.value(target)
+		}
+	}
+}
+
+// ApplyGenericOption applies to applier if genericOption matches T
+func ApplyGenericOption[T any](options []Option, applier func(T)) {
+	for _, option := range options {
+		switch option := option.(type) {
+		case genericOption[T]:
+			applier(option.value)
+		}
+	}
+}
+
+// AddIfAbundant adds a generic Option for T if value is abundant
+func AddIfAbundant[T any](options []Option, value T) []Option {
+	for _, option := range options {
+		switch option.(type) {
+		case genericOption[T]:
+			// We have a match so nothing to do
+			return options
+		}
+	}
+	return append(options, genericOption[T]{value: value})
+}
+
+// ExtractIfPresent extracts T if present
+func ExtractIfPresent[T any](options []Option) (T, bool) {
+	for _, option := range options {
+		switch option := option.(type) {
+		case genericOption[T]:
+			return option.value, true
+		}
+	}
+	return *new(T), false
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_options_test.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_options_test.go
new file mode 100644
index 0000000..4da7cf0
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_options_test.go
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
+	"github.com/apache/plc4x/plc4go/spi"
+)
+
+func TestAddIfAbundant(t *testing.T) {
+	type args[T any] struct {
+		options []Option
+		value   T
+	}
+	type testCase[T any] struct {
+		name string
+		args args[T]
+		want []Option
+	}
+	tests := []testCase[spi.Message]{
+		{
+			name: "nothing in nil out",
+			want: []Option{genericOption[spi.Message]{value: nil}},
+		},
+		{
+			name: "in nothing out",
+			args: args[spi.Message]{
+				options: []Option{
+					genericOption[spi.Message]{value: nil},
+				},
+			},
+			want: []Option{genericOption[spi.Message]{value: nil}},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := AddIfAbundant(tt.args.options, tt.args.value); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("AddIfAbundant() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestAddIfAbundantMixed(t *testing.T) {
+	var initialOptions []Option
+	AddIfAbundant(initialOptions, genericOption[spi.Message]{})
+	AddIfAbundant(initialOptions, genericOption[string]{})
+	AddIfAbundant(initialOptions, genericOption[int]{})
+	AddIfAbundant(initialOptions, genericOption[uint]{})
+}
+
+func TestAddIfAbundantCheckCollisions(t *testing.T) {
+	t.Run("bigger to smaller", func(t *testing.T) {
+		someMessage := genericOption[spi.Message]{}
+		aNLM := readWriteModel.NLM(nil)
+		initialOptions := []Option{someMessage}
+		enrichedOptions := AddIfAbundant(initialOptions, aNLM)
+		assert.Len(t, enrichedOptions, 2)
+		assert.Contains(t, enrichedOptions, someMessage)
+		assert.Contains(t, enrichedOptions, genericOption[readWriteModel.NLM]{value: aNLM})
+		assert.Equal(t, enrichedOptions, []Option{someMessage, genericOption[readWriteModel.NLM]{value: aNLM}})
+	})
+	t.Run("smaller to bigger", func(t *testing.T) {
+		someMessage := spi.Message(nil)
+		aNLM := genericOption[readWriteModel.NLM]{}
+		initialOptions := []Option{aNLM}
+		enrichedOptions := AddIfAbundant(initialOptions, someMessage)
+		assert.Len(t, enrichedOptions, 2)
+		assert.Contains(t, enrichedOptions, genericOption[spi.Message]{value: someMessage})
+		assert.Contains(t, enrichedOptions, aNLM)
+		assert.Equal(t, enrichedOptions, []Option{aNLM, genericOption[spi.Message]{value: someMessage}})
+	})
+	t.Run("does not collide", func(t *testing.T) {
+		someMessage := genericOption[spi.Message]{}
+		aNLM := genericOption[readWriteModel.NLM]{}
+		aAPDU := genericOption[readWriteModel.APDU]{}
+		initialOptions := []Option{someMessage}
+		enrichedOptions := AddIfAbundant(initialOptions, aNLM)
+		enrichedOptions = AddIfAbundant(enrichedOptions, aAPDU)
+		assert.Len(t, enrichedOptions, 3)
+	})
+	t.Run("empty ok", func(t *testing.T) {
+		aNLM := genericOption[readWriteModel.NLM]{}
+		aAPDU := genericOption[readWriteModel.APDU]{}
+		var initialOptions []Option
+		enrichedOptions := AddIfAbundant(initialOptions, aNLM)
+		enrichedOptions = AddIfAbundant(enrichedOptions, aAPDU)
+		assert.Len(t, enrichedOptions, 2)
+	})
+}
+
+func TestApplyGenericOption(t *testing.T) {
+	type args[T any] struct {
+		options []Option
+		applier func(T)
+	}
+	type testCase[T any] struct {
+		name string
+		args args[T]
+	}
+	tests := []testCase[string]{
+		{
+			name: "just apply",
+			args: args[string]{
+				options: []Option{genericOption[string]{}},
+				applier: func(s string) {
+
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ApplyGenericOption(tt.args.options, tt.args.applier)
+		})
+	}
+}
+
+func TestOptionalOption(t *testing.T) {
+	type args[V any, T any] struct {
+		value *V
+		opt   func(V) func(*T)
+	}
+	type testCase[V any, T any] struct {
+		name string
+		args args[V, T]
+		want func(*T)
+	}
+	tests := []testCase[spi.Message, spi.Message]{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := OptionalOption(tt.args.value, tt.args.opt); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("OptionalOption() = %v, want %v", got != nil, tt.want != nil)
+			}
+		})
+	}
+}
+
+func TestOptionalOption2(t *testing.T) {
+	type args[V1 any, V2 any, T any] struct {
+		value1 *V1
+		value2 *V2
+		opt    func(V1, V2) func(*T)
+	}
+	type testCase[V1 any, V2 any, T any] struct {
+		name string
+		args args[V1, V2, T]
+		want func(*T)
+	}
+	tests := []testCase[spi.Message, spi.Message, spi.Message]{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := OptionalOption2(tt.args.value1, tt.args.value2, tt.args.opt); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("OptionalOption2() = %v, want %v", got != nil, tt.want != nil)
+			}
+		})
+	}
+}
+
+func TestExtractIfPresent(t *testing.T) {
+	type A interface{}
+	type B interface{ A }
+	type C interface{ A }
+	type D struct{}
+	type E interface{}
+	someA := genericOption[A]{value: "string"}
+	someB := genericOption[B]{value: 2}
+	someC := genericOption[C]{value: true}
+	someD := genericOption[*D]{value: new(D)}
+	options := []Option{someA, someB, someC, someD}
+	assert.Len(t, options, 4)
+	assert.Equal(t, options, []Option{someA, someB, someC, someD})
+	extractedA, ok := ExtractIfPresent[A](options)
+	assert.True(t, ok)
+	assert.Equal(t, someA.value, extractedA)
+	extractedB, ok := ExtractIfPresent[B](options)
+	assert.True(t, ok)
+	assert.Equal(t, someB.value, extractedB)
+	extractedC, ok := ExtractIfPresent[C](options)
+	assert.True(t, ok)
+	assert.Equal(t, someC.value, extractedC)
+	extractedD, ok := ExtractIfPresent[*D](options)
+	assert.True(t, ok)
+	assert.Same(t, someD.value, extractedD)
+	extractedE, ok := ExtractIfPresent[*E](options)
+	assert.False(t, ok)
+	assert.Nil(t, extractedE)
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/comp/comp_plc4x.go b/plc4go/internal/bacnetip/bacgopes/comp/comp_plc4x.go
new file mode 100644
index 0000000..6a8304c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/comp/comp_plc4x.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package comp
+
+import (
+	readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
+	"github.com/apache/plc4x/plc4go/spi"
+)
+
+// AddRootMessageIfAbundant can be used to add a spi.Message if not present
+func AddRootMessageIfAbundant(options []Option, rootMessage spi.Message) []Option {
+	return AddIfAbundant(options, rootMessage)
+}
+
+// WithRootMessage can be used to bubble up a spi.Message
+func WithRootMessage(rootMessage spi.Message) Option {
+	return AsOption(rootMessage)
+}
+
+// ExtractRootMessage gets a spi.Message if present
+func ExtractRootMessage(options []Option) (rootMessage spi.Message) {
+	rootMessage, _ = ExtractIfPresent[spi.Message](options)
+	return
+}
+
+// AddNLMIfAbundant can be used to add a readWriteModel.NLM if not present
+func AddNLMIfAbundant(options []Option, nlm readWriteModel.NLM) []Option {
+	return AddIfAbundant(options, nlm)
+}
+
+// WithNLM can be used to bubble up a readWriteModel.NLM
+func WithNLM(nlm readWriteModel.NLM) Option {
+	return AsOption(nlm)
+}
+
+// ExtractNLM gets a readWriteModel.NLM if present
+func ExtractNLM(options []Option) (nlm readWriteModel.NLM) {
+	nlm, _ = ExtractIfPresent[readWriteModel.NLM](options)
+	return nil
+}
+
+// WithAPDU can be used to bubble up a readWriteModel.APDU
+func WithAPDU(apdu readWriteModel.APDU) Option {
+	return AsOption(apdu)
+}
+
+// ExtractAPDU gets a readWriteModel.APDU if present
+func ExtractAPDU(options []Option) (apdu readWriteModel.APDU) {
+	apdu, _ = ExtractIfPresent[readWriteModel.APDU](options)
+	return nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata.go b/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata.go
index 9fd3cae..1d3ba03 100644
--- a/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata.go
+++ b/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata.go
@@ -55,15 +55,25 @@
 }
 
 // TODO: finish
-func SequenceOf[T any](b func(arg Arg) (*T, error)) func(Args, KWArgs) (ElementKlass, error) {
+func SequenceOfE[T any](b func(arg Arg) (*T, error)) func(Args, KWArgs) (ElementKlass, error) {
 	panic("finish me")
 }
 
-func SequenceOfs[T any](b func(args Args) (*T, error)) func(Args, KWArgs) (ElementKlass, error) {
+func SequenceOfsE[T any](b func(args Args) (*T, error)) func(Args, KWArgs) (ElementKlass, error) {
 	panic("finish me")
 }
 
 // TODO: finish // convert to kwArgs and check wtf we are doing here...
-func ArrayOf[T any](b func(arg Arg) (*T, error), fixedLength int, prototype any) func(Args, KWArgs) (ElementKlass, error) {
+func ArrayOfE[T any](b func(arg Arg) (*T, error), fixedLength int, prototype any) func(Args, KWArgs) (ElementKlass, error) {
+	panic("finish me")
+}
+
+// TODO: finish // convert to kwArgs and check wtf we are doing here...
+func ArrayOfsE[T any](b func(args Args) (*T, error), fixedLength int, prototype any) func(Args, KWArgs) (ElementKlass, error) {
+	panic("finish me")
+}
+
+// TODO: finish // convert to kwArgs and check wtf we are doing here...
+func ListOfE[T any](b func(arg Arg) (*T, error)) func(Args) (*T, error) {
 	panic("finish me")
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata_Sequence.go b/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata_Sequence.go
index 9800e97..97f1d86 100644
--- a/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata_Sequence.go
+++ b/plc4go/internal/bacnetip/bacgopes/constructeddata/constructeddata_Sequence.go
@@ -20,11 +20,15 @@
 package constructeddata
 
 import (
+	"fmt"
+	"io"
 	"reflect"
+	"strings"
 
 	"github.com/pkg/errors"
 
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
 	readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 )
@@ -41,7 +45,6 @@
 	SetSequence(s *Sequence)
 }
 
-// TODO: finish
 type Sequence struct {
 	_contract        SequenceContract
 	sequenceElements []Element
@@ -49,13 +52,11 @@
 }
 
 // NewSequence Create a sequence element, optionally providing attribute/property values.
-func NewSequence(args Args, kwArgs KWArgs, opts ...func(*Sequence)) (*Sequence, error) {
+func NewSequence(args Args, kwArgs KWArgs, options ...Option) (*Sequence, error) {
 	s := &Sequence{
 		attr: make(map[string]any),
 	}
-	for _, opt := range opts {
-		opt(s)
-	}
+	ApplyAppliers(options, s)
 	if s._contract == nil {
 		s._contract = s
 	} else {
@@ -98,10 +99,8 @@
 	return s, nil
 }
 
-func WithSequenceExtension(contract SequenceContractRequirement) func(*Sequence) {
-	return func(s *Sequence) {
-		s._contract = contract
-	}
+func WithSequenceExtension(contract SequenceContractRequirement) GenericApplier[*Sequence] {
+	return WrapGenericApplier(func(s *Sequence) { s._contract = contract })
 }
 
 func (a *Sequence) GetSequenceElements() []Element {
@@ -118,6 +117,9 @@
 	if !ok {
 		return errors.New("arg is not a TagList")
 	}
+	if _debug != nil {
+		_debug("encode %r", tagList)
+	}
 
 	for _, element := range a._contract.GetSequenceElements() {
 		value, ok := a.attr[element.GetName()]
@@ -225,9 +227,15 @@
 	if !ok {
 		return errors.New("arg is not a TagList")
 	}
+	if _debug != nil {
+		_debug("decode %r", tagList)
+	}
 
 	for _, element := range a._contract.GetSequenceElements() {
 		tag := tagList.Peek()
+		if _debug != nil {
+			_debug("    - element, tag: %r, %r", element, tag)
+		}
 
 		elementKlass, err := element.GetKlass()(Nothing())
 		if err != nil {
@@ -316,3 +324,52 @@
 	}
 	return nil
 }
+
+func (a *Sequence) PrintDebugContents(indent int, file io.Writer, _ids []uintptr) {
+	for _, element := range a.sequenceElements {
+		value, ok := a.GetAttr(element.GetName())
+		if element.IsOptional() && !ok {
+			continue
+		} else if !element.IsOptional() && !ok {
+			_, _ = fmt.Fprintf(file, "%s%s is a missing required element of %s\n", strings.Repeat("    ", indent), element.GetName(), StructName())
+			continue
+		}
+
+		elementKlass, err := element.GetKlass()(Nothing())
+		if err != nil {
+			if _debug != nil {
+				_debug("can't get zero object")
+			}
+			return
+		}
+		_, elementInSequenceOfClasses := _sequenceOfClasses[elementKlass]
+		_, elementInListOfClasses := _listOfClasses[elementKlass]
+		isAtomic := false
+		isAnyAtomic := false
+		switch elementKlass.(type) {
+		case IsAtomic:
+			isAtomic = true
+		case IsAnyAtomic:
+			isAnyAtomic = true
+		}
+		isValueSubOfElementKlass := false // TODO: how to figure that out??
+		if elementInSequenceOfClasses || elementInListOfClasses {
+			_, _ = fmt.Fprintf(file, "%s%s\n", strings.Repeat("    ", indent), element.GetName())
+			helper, err := element.GetKlass()(NA(value), NoKWArgs())
+			if err != nil {
+				if _debug != nil {
+					_debug("    - helper class %s, err: %v", element.GetName(), err)
+				}
+				return
+			}
+			helper.(DebugContentPrinter).PrintDebugContents(indent+1, file, _ids)
+		} else if isAtomic || isAnyAtomic {
+			printVerb := VerbForType(value, 'r')
+			_, _ = fmt.Fprintf(file, "%s%s = "+string(printVerb)+"\n", strings.Repeat("    ", indent), element.GetName(), value)
+		} else if isValueSubOfElementKlass {
+			value.(DebugContentPrinter).PrintDebugContents(indent+1, file, _ids)
+		} else {
+			_, _ = fmt.Fprintf(file, "%s%s must be a %T\n", strings.Repeat("    ", indent), element.GetName(), element.GetKlass())
+		}
+	}
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/debugging/debugging.go b/plc4go/internal/bacnetip/bacgopes/debugging/debugging.go
index 7602662..8941aeb 100644
--- a/plc4go/internal/bacnetip/bacgopes/debugging/debugging.go
+++ b/plc4go/internal/bacnetip/bacgopes/debugging/debugging.go
@@ -19,534 +19,15 @@
 
 package debugging
 
-import (
-	"encoding/hex"
-	"fmt"
-	"io"
-	"os"
-	"path"
-	"reflect"
-	"regexp"
-	"runtime"
-	"slices"
-	"strings"
-	"time"
-	"unsafe"
-)
-
-var _isDebuggingActive = false
 var _debug = CreateDebugPrinter()
 
-func Btox(data []byte, sep string) string {
-	hexString := hex.EncodeToString(data)
-	if sep != "" {
-		pairs := make([]string, len(hexString)/2)
-		for i := 0; i < len(hexString)-1; i += 2 {
-			pairs[i/2] = hexString[i : i+2]
-		}
-		hexString = strings.Join(pairs, ".")
-	}
-	return hexString
-}
-
-func Xtob(hexString string) ([]byte, error) {
-	compile, err := regexp.Compile("[^0-9a-fA-F]")
-	if err != nil {
-		return nil, err
-	}
-	replaceAll := compile.ReplaceAll([]byte(hexString), nil)
-	decodeString, err := hex.DecodeString(string(replaceAll))
-	if err != nil {
-		return nil, err
-	}
-	return decodeString, nil
-}
-
-type Debuggable interface {
-	GetDebugAttr(attr string) any
-}
-
-type DebugContentPrinter interface {
-	PrintDebugContents(indent int, file io.Writer, _ids []uintptr)
-}
-
-type DebugContents struct {
-	debuggables        []Debuggable
-	debuggableContents map[Debuggable][]string
-	extraPrinters      []DebugContentPrinter
-}
-
-func NewDebugContents(debuggable Debuggable, contents ...string) *DebugContents {
-	return &DebugContents{
-		debuggables: []Debuggable{debuggable},
-		debuggableContents: map[Debuggable][]string{
-			debuggable: contents,
-		},
-	}
-}
-
-var _ DebugContentPrinter = (*DebugContents)(nil)
-
-func (d *DebugContents) AddExtraPrinters(printers ...DebugContentPrinter) {
-	d.extraPrinters = append(d.extraPrinters, printers...)
-}
-
-func (d *DebugContents) AddDebugContents(debuggable Debuggable, contents ...string) {
-	d.debuggables = append(d.debuggables, debuggable)
-	d.debuggableContents[debuggable] = contents
-}
-
-func (d *DebugContents) Format(s fmt.State, v rune) {
-	if d == nil {
-		if _debug != nil {
-			_debug("nil debug attempt") // TODO: this should no happen
-		}
-		return
-	}
-	switch v {
-	case 's', 'v':
-		// TODO: check if that hacky hacky makes sense
-		if len(d.debuggables) > 0 {
-			debuggable := d.debuggables[0]
-			_, _ = fmt.Fprintf(s, "<%s at %p>", QualifiedTypeName(debuggable), debuggable)
-		}
-	case 'r':
-		// TODO: check if that hacky hacky makes sense
-		if len(d.debuggables) > 0 {
-			debuggable := d.debuggables[0]
-			_, _ = fmt.Fprintf(s, "<%s at %p>\n", QualifiedTypeName(debuggable), debuggable)
-			_, _ = fmt.Fprintf(s, "    <%s at %p>\n", QualifiedTypeName(debuggable), debuggable) // TODO: why is this duplicated?
-		}
-		d.PrintDebugContents(2, s, nil)
-	}
-}
-
-func (d *DebugContents) PrintDebugContents(indent int, file io.Writer, _ids []uintptr) {
-	if indent == 0 {
-		indent = 1
-	}
-	if file == nil {
-		file = os.Stderr
-	}
-
-	// loop through the debuggables and look for debugContents
-	attrToDebuggable := map[string]Debuggable{} // Reverse map to know where to get the attr from
-	var attrs []string
-	cids := map[uintptr]struct{}{
-		uintptr(unsafe.Pointer(d)): {},
-	}
-	var ownFn []DebugContentPrinter // TODO: make them member and add a add method
-	for _, debuggable := range d.debuggables {
-		debugContents, ok := d.debuggableContents[debuggable]
-		if !ok {
-			continue
-		}
-
-		// already seen it?
-		if _, ok := cids[uintptr(unsafe.Pointer(&debuggable))]; ok {
-			// continue // TODO: seems the logic is broken: e.g. RecurringTask is seen but it should be a own entity
-		}
-		cids[uintptr(unsafe.Pointer(&debuggable))] = struct{}{}
-
-		for _, attr := range debugContents {
-			if !slices.Contains(attrs, attr) {
-				cleanAttr := attr
-				for strings.HasSuffix(cleanAttr, "-") || strings.HasSuffix(cleanAttr, "*") || strings.HasSuffix(cleanAttr, "+") {
-					cleanAttr = strings.TrimSuffix(cleanAttr, "-")
-					cleanAttr = strings.TrimSuffix(cleanAttr, "*")
-					cleanAttr = strings.TrimSuffix(cleanAttr, "+")
-				}
-				attrToDebuggable[cleanAttr] = debuggable
-				attrs = append(attrs, attr)
-			}
-		}
-	}
-
-	// a bit of debugging
-	if _debug != nil {
-		_debug("    - attrs: %r", attrs)
-		//_debug("    - ownFn: %r", ownFn)
-	}
-
-	for _, printer := range d.extraPrinters {
-		printer.PrintDebugContents(indent, file, _ids)
-	}
-	for _, attr := range attrs {
-		// assume you're going deep, but not into lists and dicts
-		goDeep := true
-		goListDict := false
-		goHexed := false
-
-		// attribute list might want to go deep
-		if strings.HasSuffix(attr, "-") {
-			goDeep = false
-			attr = attr[:len(attr)-1]
-		} else if strings.HasSuffix(attr, "*") {
-			goHexed = true
-			attr = attr[:len(attr)-1]
-		} else if strings.HasSuffix(attr, "+") {
-			goDeep = false
-			goListDict = true
-			attr = attr[:len(attr)-1]
-			if strings.HasSuffix(attr, "+") {
-				goDeep = true
-				attr = attr[:len(attr)-1]
-			}
-		}
-
-		debuggable := attrToDebuggable[attr]
-		if debuggable == nil {
-			panic("attr misconfiguration " + attr)
-		}
-		value := debuggable.GetDebugAttr(attr)
-
-		// skip nil
-		if isNil(value) {
-			continue
-		}
-
-		// standard output
-		if goListDict && isList(value) {
-			list, ok := toList(value)
-			if !ok {
-				panic("impossible")
-			}
-			_, _ = fmt.Fprintf(file, "%s%s = [\n", strings.Repeat("    ", indent), attr)
-			indent += 1
-			for i, elem := range list {
-				_, _ = fmt.Fprintf(file, "%s[%d] %r\n", strings.Repeat("    ", indent), i, elem)
-				if deepDebugContent, ok := elem.(interface {
-					DebugContents(int, io.Writer, []uintptr)
-				}); goDeep && ok {
-					if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
-						_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
-						deepDebugContent.DebugContents(indent+1, file, _ids)
-					}
-				}
-			}
-			indent -= 1
-			_, _ = fmt.Fprintf(file, "%s    ]\n", strings.Repeat("    ", indent))
-		} else if goListDict && isDict(value) {
-			_map, ok := toMap(value)
-			if !ok {
-				panic("impossible")
-			}
-			_, _ = fmt.Fprintf(file, "%s%s = {\n", strings.Repeat("    ", indent), attr)
-			indent += 1
-			for key, elem := range _map {
-				keyPrintVerb := verbForType(key, 'r')
-				elemPrintVerb := verbForType(elem, 'r')
-				_, _ = fmt.Fprintf(file, "%s"+string(keyPrintVerb)+" : "+string(elemPrintVerb)+"\n", strings.Repeat("    ", indent), key, elem)
-				if deepDebugContent, ok := elem.(interface {
-					DebugContents(int, io.Writer, []uintptr)
-				}); goDeep && ok {
-					if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
-						_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
-						deepDebugContent.DebugContents(indent+1, file, _ids)
-					}
-				}
-			}
-			indent -= 1
-			_, _ = fmt.Fprintf(file, "%s    }\n", strings.Repeat("    ", indent))
-		} else if goHexed && isString(value) { // TODO: add support
-			panic("add support")
-		} else {
-			printVerb := verbForType(value, 'r')
-			_, _ = fmt.Fprintf(file, "%s%s = %"+string(printVerb)+"\n", strings.Repeat("    ", indent), attr, value)
-
-			// go nested if it is debuggable
-			if deepDebugContent, ok := value.(DebugContentPrinter); goDeep && ok {
-				if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
-					_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
-					deepDebugContent.PrintDebugContents(indent+1, file, _ids)
-				}
-			}
-		}
-	}
-
-	// go through the functions
-	slices.Reverse(ownFn)
-	for _, printer := range ownFn {
-		printer.PrintDebugContents(indent, file, _ids)
-	}
-}
-
-func isList(input any) bool {
-	reflectValue := reflect.ValueOf(input)
-	switch reflectValue.Kind() {
-	case reflect.Slice, reflect.Array:
-		return true
-	default:
-		return false
-	}
-}
-
-func toList(input any) (list []any, ok bool) {
-	reflectValue := reflect.ValueOf(input)
-	switch reflectValue.Kind() {
-	case reflect.Slice, reflect.Array:
-	default:
-		return nil, false
-	}
-	list = make([]any, reflectValue.Len())
-	for i := 0; i < reflectValue.Len(); i++ {
-		elem := reflectValue.Index(i).Interface()
-		list[i] = elem
-	}
-	return list, true
-}
-
-func isDict(input any) bool {
-	reflectValue := reflect.ValueOf(input)
-	switch reflectValue.Kind() {
-	case reflect.Map:
-		return true
-	default:
-		return false
-	}
-}
-
-func toMap(input any) (_map map[string]any, ok bool) {
-	reflectValue := reflect.ValueOf(input)
-	switch reflectValue.Kind() {
-	case reflect.Map:
-	default:
-		return nil, false
-	}
-	_map = make(map[string]any)
-	for _, k := range reflectValue.MapKeys() {
-		value := reflectValue.MapIndex(k)
-		_map[k.String()] = value.Interface() //TODO: check if we further need to convert map key
-	}
-	return _map, true
-}
-
-func isString(input any) bool {
-	_, ok := input.(string)
-	return ok
-}
-
-func TypeName(anything any) string {
-	typeOf := reflect.TypeOf(anything)
-	if typeOf.Kind() == reflect.Ptr {
-		typeOf = typeOf.Elem()
-	}
-	return typeOf.Name()
-}
-
-func QualifiedTypeName(anything any) string {
-	typeOf := reflect.TypeOf(anything)
-	if typeOf.Kind() == reflect.Ptr {
-		typeOf = typeOf.Elem()
-	}
-	typeNameString := "bacgopes." + typeOf.String()
-	if customProjectName != "" {
-		typeNameString = strings.ReplaceAll(typeNameString, projectName, customProjectName)
-	}
-	return typeNameString
-}
-
-// TODO: migrate comp debug logger to here...
-type LoggingFormatter struct {
-	// TODO: implement me
-}
-
-type DefaultRFormatter struct {
-	header        string
-	extraPrinters []DebugContentPrinter
-}
-
-func NewDefaultRFormatter(extraPrinters ...DebugContentPrinter) *DefaultRFormatter {
-	pc, file, _, ok := runtime.Caller(1)
-	if !ok {
-		panic("oh no")
-	}
-	dir := path.Dir(file)
-	rootIndex := strings.Index(dir, "bacgopes")
-	dir = dir[rootIndex:]
-	dirPrefix := path.Base(dir) + "_"
-	base := path.Base(file)
-	prefix := strings.TrimSuffix(base, ".go")
-	prefix = strings.TrimPrefix(prefix, dirPrefix)
-	qualifier := strings.ReplaceAll(dirPrefix, "_", ".")
-	header := fmt.Sprintf("<%s at 0x%x>", "bacgopes."+qualifier+prefix, pc)
-	if customProjectName != "" {
-		header = strings.ReplaceAll(header, projectName, customProjectName)
-	}
-	return &DefaultRFormatter{
-		header:        header,
-		extraPrinters: extraPrinters,
-	}
-}
-
-func (d *DefaultRFormatter) Format(s fmt.State, v rune) {
-	if d.header == "" && len(d.extraPrinters) == 0 {
-		panic("misconfiguration")
-	}
-	switch v {
-	case 'r':
-		_, _ = s.Write([]byte(d.header))
-		if len(d.extraPrinters) > 0 {
-			_, _ = s.Write([]byte("\n"))
-		}
-		for _, printer := range d.extraPrinters {
-			printer.PrintDebugContents(1, s, nil)
-		}
-	case 'v', 's':
-		_, _ = s.Write([]byte(d.header))
-	}
-}
-
-func StructName() string {
-	_, file, _, ok := runtime.Caller(1)
-	if !ok {
-		return ""
-	}
-	dir := path.Dir(file)
-	rootIndex := strings.Index(dir, "bacgopes")
-	dir = dir[rootIndex:]
-	dirPrefix := path.Base(dir) + "_"
-	base := path.Base(file)
-	prefix := strings.TrimSuffix(base, ".go")
-	return strings.TrimPrefix(prefix, dirPrefix)
-}
-
-type DebugPrinter = func(format string, a ...any)
-
-const projectName = "bacgopes"
-
-var customProjectName = os.Getenv("BACGOPES_DEBUG_CUSTOM_PROJECT_NAME")
-var customReplaces map[string]string
-
-func init() {
-	customReplaces = map[string]string{}
-	for _, replace := range strings.Split(os.Getenv("BACGOPES_DEBUG_CUSTOM_REPLACES"), ",") {
-		if replace == "" || !strings.Contains(replace, "=") {
-			continue
-		}
-		kv := strings.SplitN(replace, "=", 2)
-		if len(kv) != 2 {
-			panic("invalid replace " + replace)
-		}
-		customReplaces[kv[0]] = kv[1]
-	}
-}
-
-func CreateDebugPrinter() DebugPrinter {
-	_, file, _, ok := runtime.Caller(1)
-	if !ok {
-		return nil
-	}
-	dir := path.Dir(file)
-	rootIndex := strings.Index(dir, "bacgopes")
-	dir = dir[rootIndex:]
-	qualifier := strings.ReplaceAll(dir, "/", ".")
-	dirPrefix := path.Base(dir) + "_"
-
-	bacgopesDebug := os.Getenv("BACGOPES_DEBUG")
-	if strings.Contains(bacgopesDebug, qualifier) {
-		_isDebuggingActive = true
-		return func(format string, a ...any) {
-			pc, file, _, ok := runtime.Caller(1)
-			if !ok {
-				return
-			}
-			base := path.Base(file)
-			prefix := strings.TrimSuffix(base, ".go")
-			if !strings.HasPrefix(prefix, dirPrefix) && !strings.Contains(prefix, "tests") && false { // TODO: disabled for now as it makes more trouble for the rest
-				// Attach the fuction name // TODO: check if that makes sense, only a workaround for bind at the moment
-				details := runtime.FuncForPC(pc)
-				name := details.Name()
-				name = name[strings.LastIndex(name, ".")+1:]
-				prefix = strings.ToLower(name)
-			}
-			prefix = strings.TrimPrefix(prefix, dirPrefix)
-			formatString := "DEBUG:" + qualifier + "." + prefix + ":" + format + "\n"
-			formatString = cleanupFormatString(formatString)
-			if customProjectName != "" {
-				formatString = strings.ReplaceAll(formatString, projectName, customProjectName)
-			}
-			formatString = fixVerbs(formatString, a...)
-			output := fmt.Sprintf(formatString, a...)
-			if strings.HasSuffix(output, "\n\n") { // TODO: another hacky workaround
-				output = strings.TrimSuffix(output, "\n")
-			}
-			for k, v := range customReplaces {
-				output = strings.ReplaceAll(output, k, v)
-			}
-			_, _ = os.Stdout.Write([]byte(output))
-		}
-	}
-	return nil
-}
+var _isDebuggingActive = false
 
 func IsDebuggingActive() bool {
 	return _isDebuggingActive
 }
 
-func cleanupFormatString(s string) string {
-	// TODO: investigate via comm.comm is happening
-	s = strings.ReplaceAll(s, ".comm.comm:", ".comm:")
-	s = strings.ReplaceAll(s, "pdu.comm_PCI:", "comm.PCI:")
-	s = strings.ReplaceAll(s, "pdu.comm_PDUData:", "comm.PDUData:")
-	s = strings.ReplaceAll(s, "DEBUG:"+projectName+".tests", "DEBUG:tests")
-	return s
-}
-
-func fixVerbs(formatString string, values ...any) string {
-	length := len(formatString)
-	verbNumber := -1
-	for i, r := range formatString {
-		switch r {
-		case '%':
-			nextIndex := i + 1
-			if nextIndex >= length {
-				continue
-			}
-			followRune := formatString[nextIndex]
-			if followRune != '%' {
-				verbNumber++
-			}
-			if followRune == 'r' && verbNumber < len(values) { // TODO: this completely breaks at indexed verbs... better fix assap
-				runes := []rune(formatString)
-				runes[nextIndex] = verbForType(values[verbNumber], 'r')
-				formatString = string(runes)
-			}
-		}
-	}
-	return formatString
-}
-
-func verbForType(value any, printVerb rune) rune {
-	switch value.(type) {
-	case string:
-		printVerb = 's'
-	case bool:
-		printVerb = 't'
-	case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr:
-		printVerb = 'd'
-	case float32, float64:
-		printVerb = 'f'
-	case complex64, complex128:
-		printVerb = 'v' // TODO: what is it meant for?
-	case time.Time, time.Duration:
-		printVerb = 's'
-	case []byte:
-		printVerb = 'v'
-	}
-	return printVerb
-}
-
-// clone from comp to avoid circular dependencies // TODO: maybe move Btox somewhere else or come up with something smarter there
-func isNil(v interface{}) bool {
-	if v == nil {
-		return true
-	}
-	valueOf := reflect.ValueOf(v)
-	switch valueOf.Kind() {
-	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
-		return valueOf.IsNil()
-	default:
-		return false
-	}
+// TODO: implement
+type LoggingFormatter struct {
+	// TODO: implement me
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugContents.go b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugContents.go
new file mode 100644
index 0000000..33f11d5
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugContents.go
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package debugging
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"slices"
+	"strings"
+	"unsafe"
+)
+
+type Debuggable interface {
+	GetDebugAttr(attr string) any
+}
+
+type DebugContentPrinter interface {
+	PrintDebugContents(indent int, file io.Writer, _ids []uintptr)
+}
+
+type DebugContents struct {
+	debuggables        []Debuggable
+	debuggableContents map[Debuggable][]string
+	extraPrinters      []DebugContentPrinter
+}
+
+func NewDebugContents(debuggable Debuggable, contents ...string) *DebugContents {
+	return &DebugContents{
+		debuggables: []Debuggable{debuggable},
+		debuggableContents: map[Debuggable][]string{
+			debuggable: contents,
+		},
+	}
+}
+
+var _ DebugContentPrinter = (*DebugContents)(nil)
+
+func (d *DebugContents) AddExtraPrinters(printers ...DebugContentPrinter) {
+	d.extraPrinters = append(d.extraPrinters, printers...)
+}
+
+func (d *DebugContents) AddDebugContents(debuggable Debuggable, contents ...string) {
+	d.debuggables = append(d.debuggables, debuggable)
+	d.debuggableContents[debuggable] = contents
+}
+
+func (d *DebugContents) Format(s fmt.State, v rune) {
+	if d == nil {
+		if _debug != nil {
+			_debug("nil debug attempt") // TODO: this should no happen
+		}
+		return
+	}
+	switch v {
+	case 's', 'v':
+		// TODO: check if that hacky hacky makes sense
+		if len(d.debuggables) > 0 {
+			debuggable := d.debuggables[0]
+			_, _ = fmt.Fprintf(s, "<%s at %p>", QualifiedTypeName(debuggable), debuggable)
+		}
+	case 'r':
+		// TODO: check if that hacky hacky makes sense
+		if len(d.debuggables) > 0 {
+			debuggable := d.debuggables[0]
+			_, _ = fmt.Fprintf(s, "<%s at %p>\n", QualifiedTypeName(debuggable), debuggable)
+			_, _ = fmt.Fprintf(s, "    <%s at %p>\n", QualifiedTypeName(debuggable), debuggable) // TODO: why is this duplicated?
+		}
+		d.PrintDebugContents(2, s, nil)
+	}
+}
+
+func (d *DebugContents) PrintDebugContents(indent int, file io.Writer, _ids []uintptr) {
+	if indent == 0 {
+		indent = 1
+	}
+	if file == nil {
+		file = os.Stderr
+	}
+
+	// loop through the debuggables and look for debugContents
+	attrToDebuggable := map[string]Debuggable{} // Reverse map to know where to get the attr from
+	var attrs []string
+	cids := map[uintptr]struct{}{
+		uintptr(unsafe.Pointer(d)): {},
+	}
+	var ownFn []DebugContentPrinter // TODO: make them member and add a add method
+	for _, debuggable := range d.debuggables {
+		debugContents, ok := d.debuggableContents[debuggable]
+		if !ok {
+			continue
+		}
+
+		// already seen it?
+		if _, ok := cids[uintptr(unsafe.Pointer(&debuggable))]; ok {
+			// continue // TODO: seems the logic is broken: e.g. RecurringTask is seen but it should be a own entity
+		}
+		cids[uintptr(unsafe.Pointer(&debuggable))] = struct{}{}
+
+		for _, attr := range debugContents {
+			if !slices.Contains(attrs, attr) {
+				cleanAttr := attr
+				for strings.HasSuffix(cleanAttr, "-") || strings.HasSuffix(cleanAttr, "*") || strings.HasSuffix(cleanAttr, "+") {
+					cleanAttr = strings.TrimSuffix(cleanAttr, "-")
+					cleanAttr = strings.TrimSuffix(cleanAttr, "*")
+					cleanAttr = strings.TrimSuffix(cleanAttr, "+")
+				}
+				attrToDebuggable[cleanAttr] = debuggable
+				attrs = append(attrs, attr)
+			}
+		}
+	}
+
+	// a bit of debugging
+	if _debug != nil {
+		_debug("    - attrs: %r", attrs)
+		//_debug("    - ownFn: %r", ownFn)
+	}
+
+	for _, printer := range d.extraPrinters {
+		printer.PrintDebugContents(indent, file, _ids)
+	}
+	for _, attr := range attrs {
+		// assume you're going deep, but not into lists and dicts
+		goDeep := true
+		goListDict := false
+		goHexed := false
+
+		// attribute list might want to go deep
+		if strings.HasSuffix(attr, "-") {
+			goDeep = false
+			attr = attr[:len(attr)-1]
+		} else if strings.HasSuffix(attr, "*") {
+			goHexed = true
+			attr = attr[:len(attr)-1]
+		} else if strings.HasSuffix(attr, "+") {
+			goDeep = false
+			goListDict = true
+			attr = attr[:len(attr)-1]
+			if strings.HasSuffix(attr, "+") {
+				goDeep = true
+				attr = attr[:len(attr)-1]
+			}
+		}
+
+		debuggable := attrToDebuggable[attr]
+		if debuggable == nil {
+			panic("attr misconfiguration " + attr)
+		}
+		value := debuggable.GetDebugAttr(attr)
+
+		// skip nil
+		if isNil(value) {
+			continue
+		}
+
+		// standard output
+		if goListDict && isList(value) {
+			list, ok := toList(value)
+			if !ok {
+				panic("impossible")
+			}
+			_, _ = fmt.Fprintf(file, "%s%s = [\n", strings.Repeat("    ", indent), attr)
+			indent += 1
+			for i, elem := range list {
+				_, _ = fmt.Fprintf(file, "%s[%d] %r\n", strings.Repeat("    ", indent), i, elem)
+				if deepDebugContent, ok := elem.(interface {
+					DebugContents(int, io.Writer, []uintptr)
+				}); goDeep && ok {
+					if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
+						_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
+						deepDebugContent.DebugContents(indent+1, file, _ids)
+					}
+				}
+			}
+			indent -= 1
+			_, _ = fmt.Fprintf(file, "%s    ]\n", strings.Repeat("    ", indent))
+		} else if goListDict && isDict(value) {
+			_map, ok := toMap(value)
+			if !ok {
+				panic("impossible")
+			}
+			_, _ = fmt.Fprintf(file, "%s%s = {\n", strings.Repeat("    ", indent), attr)
+			indent += 1
+			for key, elem := range _map {
+				keyPrintVerb := VerbForType(key, 'r')
+				elemPrintVerb := VerbForType(elem, 'r')
+				_, _ = fmt.Fprintf(file, "%s"+string(keyPrintVerb)+" : "+string(elemPrintVerb)+"\n", strings.Repeat("    ", indent), key, elem)
+				if deepDebugContent, ok := elem.(interface {
+					DebugContents(int, io.Writer, []uintptr)
+				}); goDeep && ok {
+					if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
+						_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
+						deepDebugContent.DebugContents(indent+1, file, _ids)
+					}
+				}
+			}
+			indent -= 1
+			_, _ = fmt.Fprintf(file, "%s    }\n", strings.Repeat("    ", indent))
+		} else if goHexed && isString(value) { // TODO: add support
+			panic("add support")
+		} else {
+			printVerb := VerbForType(value, 'r')
+			_, _ = fmt.Fprintf(file, "%s%s = %"+string(printVerb)+"\n", strings.Repeat("    ", indent), attr, value)
+
+			// go nested if it is debuggable
+			if deepDebugContent, ok := value.(DebugContentPrinter); goDeep && ok {
+				if slices.Contains(_ids, uintptr(unsafe.Pointer(&deepDebugContent))) {
+					_ids = append(_ids, uintptr(unsafe.Pointer(&deepDebugContent)))
+					deepDebugContent.PrintDebugContents(indent+1, file, _ids)
+				}
+			}
+		}
+	}
+
+	// go through the functions
+	slices.Reverse(ownFn)
+	for _, printer := range ownFn {
+		printer.PrintDebugContents(indent, file, _ids)
+	}
+}
+
+func isList(input any) bool {
+	reflectValue := reflect.ValueOf(input)
+	switch reflectValue.Kind() {
+	case reflect.Slice, reflect.Array:
+		return true
+	default:
+		return false
+	}
+}
+
+func toList(input any) (list []any, ok bool) {
+	reflectValue := reflect.ValueOf(input)
+	switch reflectValue.Kind() {
+	case reflect.Slice, reflect.Array:
+	default:
+		return nil, false
+	}
+	list = make([]any, reflectValue.Len())
+	for i := 0; i < reflectValue.Len(); i++ {
+		elem := reflectValue.Index(i).Interface()
+		list[i] = elem
+	}
+	return list, true
+}
+
+func isDict(input any) bool {
+	reflectValue := reflect.ValueOf(input)
+	switch reflectValue.Kind() {
+	case reflect.Map:
+		return true
+	default:
+		return false
+	}
+}
+
+func toMap(input any) (_map map[string]any, ok bool) {
+	reflectValue := reflect.ValueOf(input)
+	switch reflectValue.Kind() {
+	case reflect.Map:
+	default:
+		return nil, false
+	}
+	_map = make(map[string]any)
+	for _, k := range reflectValue.MapKeys() {
+		value := reflectValue.MapIndex(k)
+		_map[k.String()] = value.Interface() //TODO: check if we further need to convert map key
+	}
+	return _map, true
+}
+
+func isString(input any) bool {
+	_, ok := input.(string)
+	return ok
+}
+
+func TypeName(anything any) string {
+	typeOf := reflect.TypeOf(anything)
+	if typeOf.Kind() == reflect.Ptr {
+		typeOf = typeOf.Elem()
+	}
+	return typeOf.Name()
+}
+
+func QualifiedTypeName(anything any) string {
+	typeOf := reflect.TypeOf(anything)
+	if typeOf.Kind() == reflect.Ptr {
+		typeOf = typeOf.Elem()
+	}
+	typeNameString := "bacgopes." + typeOf.String()
+	if customProjectName != "" {
+		typeNameString = strings.ReplaceAll(typeNameString, projectName, customProjectName)
+	}
+	return typeNameString
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugPrinter.go b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugPrinter.go
new file mode 100644
index 0000000..ddc8ebe
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DebugPrinter.go
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package debugging
+
+import (
+	"fmt"
+	"os"
+	"path"
+	"runtime"
+	"strings"
+)
+
+type DebugPrinter = func(format string, a ...any)
+
+const projectName = "bacgopes"
+
+var customProjectName = os.Getenv("BACGOPES_DEBUG_CUSTOM_PROJECT_NAME")
+var customReplaces map[string]string
+
+func init() {
+	customReplaces = map[string]string{}
+	for _, replace := range strings.Split(os.Getenv("BACGOPES_DEBUG_CUSTOM_REPLACES"), ",") {
+		if replace == "" || !strings.Contains(replace, "=") {
+			continue
+		}
+		kv := strings.SplitN(replace, "=", 2)
+		if len(kv) != 2 {
+			panic("invalid replace " + replace)
+		}
+		customReplaces[kv[0]] = kv[1]
+	}
+}
+
+func CreateDebugPrinter() DebugPrinter {
+	_, file, _, ok := runtime.Caller(1)
+	if !ok {
+		return nil
+	}
+	dir := path.Dir(file)
+	rootIndex := strings.Index(dir, "bacgopes")
+	dir = dir[rootIndex:]
+	qualifier := strings.ReplaceAll(dir, "/", ".")
+	switch {
+	case strings.HasPrefix(qualifier, "bacgopes.tests"):
+		qualifier = "tests" + strings.TrimPrefix(qualifier, "bacgopes.tests")
+	}
+	dirPrefix := path.Base(dir) + "_"
+
+	bacgopesDebug := os.Getenv("BACGOPES_DEBUG")
+	if strings.Contains(bacgopesDebug, qualifier) {
+		_isDebuggingActive = true
+		return func(format string, a ...any) {
+			pc, file, _, ok := runtime.Caller(1)
+			if !ok {
+				return
+			}
+			base := path.Base(file)
+			prefix := strings.TrimSuffix(base, ".go")
+			if !strings.HasPrefix(prefix, dirPrefix) && !strings.Contains(prefix, "tests") && false { // TODO: disabled for now as it makes more trouble for the rest
+				// Attach the fuction name // TODO: check if that makes sense, only a workaround for bind at the moment
+				details := runtime.FuncForPC(pc)
+				name := details.Name()
+				name = name[strings.LastIndex(name, ".")+1:]
+				prefix = strings.ToLower(name)
+			}
+			{ //TODO: temporary debug
+				if strings.Contains(qualifier, "tests.") {
+					println()
+				}
+				if strings.Contains(file, "tests") {
+					println()
+				}
+			}
+			prefix = strings.TrimPrefix(prefix, dirPrefix)
+			formatString := "DEBUG:" + qualifier + "." + prefix + ":" + format + "\n"
+			formatString = cleanupFormatString(formatString)
+			if customProjectName != "" {
+				formatString = strings.ReplaceAll(formatString, projectName, customProjectName)
+			}
+			formatString = fixVerbs(formatString, a...)
+			output := fmt.Sprintf(formatString, a...)
+			if strings.HasSuffix(output, "\n\n") { // TODO: another hacky workaround
+				output = strings.TrimSuffix(output, "\n")
+			}
+			for k, v := range customReplaces {
+				output = strings.ReplaceAll(output, k, v)
+			}
+			_, _ = os.Stdout.Write([]byte(output))
+		}
+	}
+	return nil
+}
+
+func cleanupFormatString(s string) string {
+	// TODO: investigate via comm.comm is happening
+	s = strings.ReplaceAll(s, ".comm.comm:", ".comm:")
+	s = strings.ReplaceAll(s, "pdu.comm_PCI:", "comm.PCI:")
+	s = strings.ReplaceAll(s, "pdu.comm_PDUData:", "comm.PDUData:")
+	s = strings.ReplaceAll(s, "DEBUG:"+projectName+".tests", "DEBUG:tests")
+	s = strings.ReplaceAll(s, "appservice.app_DeviceInfoCache", "app.DeviceInfoCache")
+	s = strings.ReplaceAll(s, "device_WhoIsIAmServices", "device.WhoIsIAmServices")
+	return s
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DefaultRFormatter.go b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DefaultRFormatter.go
new file mode 100644
index 0000000..ac2fca2
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_DefaultRFormatter.go
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package debugging
+
+import (
+	"fmt"
+	"path"
+	"runtime"
+	"strings"
+)
+
+type DefaultRFormatter struct {
+	header        string
+	extraPrinters []DebugContentPrinter
+}
+
+func NewDefaultRFormatter(extraPrinters ...DebugContentPrinter) *DefaultRFormatter {
+	pc, file, _, ok := runtime.Caller(1)
+	if !ok {
+		panic("oh no")
+	}
+	dir := path.Dir(file)
+	rootIndex := strings.Index(dir, "bacgopes")
+	dir = dir[rootIndex:]
+	dirPrefix := path.Base(dir) + "_"
+	base := path.Base(file)
+	prefix := strings.TrimSuffix(base, ".go")
+	prefix = strings.TrimPrefix(prefix, dirPrefix)
+	qualifier := strings.ReplaceAll(dirPrefix, "_", ".")
+	if strings.HasPrefix(qualifier, "test.") {
+		qualifier = "tests.test_" + strings.TrimPrefix(qualifier, "test.")
+	} else {
+		qualifier = "bacgopes." + qualifier
+	}
+	header := fmt.Sprintf("<%s at 0x%x>", qualifier+prefix, pc)
+	if customProjectName != "" {
+		header = strings.ReplaceAll(header, projectName, customProjectName)
+	}
+	return &DefaultRFormatter{
+		header:        header,
+		extraPrinters: extraPrinters,
+	}
+}
+
+func (d *DefaultRFormatter) Format(s fmt.State, v rune) {
+	if d.header == "" && len(d.extraPrinters) == 0 {
+		panic("misconfiguration")
+	}
+	switch v {
+	case 'r':
+		_, _ = s.Write([]byte(d.header))
+		if len(d.extraPrinters) > 0 {
+			_, _ = s.Write([]byte("\n"))
+		}
+		for _, printer := range d.extraPrinters {
+			printer.PrintDebugContents(1, s, nil)
+		}
+	case 'v', 's':
+		_, _ = s.Write([]byte(d.header))
+	}
+}
+
+func (d *DefaultRFormatter) String() string {
+	return d.header
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/debugging/debugging_commons.go b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_commons.go
new file mode 100644
index 0000000..aeeceea
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/debugging/debugging_commons.go
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package debugging
+
+import (
+	"encoding/hex"
+	"path"
+	"reflect"
+	"regexp"
+	"runtime"
+	"strings"
+	"time"
+)
+
+func Btox(data []byte, sep string) string {
+	hexString := hex.EncodeToString(data)
+	if sep != "" {
+		pairs := make([]string, len(hexString)/2)
+		for i := 0; i < len(hexString)-1; i += 2 {
+			pairs[i/2] = hexString[i : i+2]
+		}
+		hexString = strings.Join(pairs, ".")
+	}
+	return hexString
+}
+
+func Xtob(hexString string) ([]byte, error) {
+	compile, err := regexp.Compile("[^0-9a-fA-F]")
+	if err != nil {
+		return nil, err
+	}
+	replaceAll := compile.ReplaceAll([]byte(hexString), nil)
+	decodeString, err := hex.DecodeString(string(replaceAll))
+	if err != nil {
+		return nil, err
+	}
+	return decodeString, nil
+}
+
+func fixVerbs(formatString string, values ...any) string {
+	length := len(formatString)
+	verbNumber := -1
+	for i, r := range formatString {
+		switch r {
+		case '%':
+			nextIndex := i + 1
+			if nextIndex >= length {
+				continue
+			}
+			followRune := formatString[nextIndex]
+			if followRune != '%' {
+				verbNumber++
+			}
+			if followRune == 'r' && verbNumber < len(values) { // TODO: this completely breaks at indexed verbs... better fix assap
+				runes := []rune(formatString)
+				runes[nextIndex] = VerbForType(values[verbNumber], 'r')
+				formatString = string(runes)
+			}
+		}
+	}
+	return formatString
+}
+
+func VerbForType(value any, printVerb rune) rune {
+	if isNil(value) {
+		return 'p' // hack to avoid panic
+	}
+	switch value.(type) {
+	case string:
+		printVerb = 's'
+	case bool:
+		printVerb = 't'
+	case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr:
+		printVerb = 'd'
+	case float32, float64:
+		printVerb = 'f'
+	case complex64, complex128:
+		printVerb = 'v' // TODO: what is it meant for?
+	case time.Time, time.Duration:
+		printVerb = 's'
+	case []byte:
+		printVerb = 'v'
+	case interface{ PLC4XEnumName() string }: // shortcut to handle model enums
+		printVerb = 'd'
+	}
+	return printVerb
+}
+
+// clone from comp to avoid circular dependencies // TODO: maybe move Btox somewhere else or come up with something smarter there
+func isNil(v interface{}) bool {
+	if v == nil {
+		return true
+	}
+	valueOf := reflect.ValueOf(v)
+	switch valueOf.Kind() {
+	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
+		return valueOf.IsNil()
+	default:
+		return false
+	}
+}
+
+func StructName() string {
+	_, file, _, ok := runtime.Caller(1)
+	if !ok {
+		return ""
+	}
+	dir := path.Dir(file)
+	rootIndex := strings.Index(dir, "bacgopes")
+	dir = dir[rootIndex:]
+	dirPrefix := path.Base(dir) + "_"
+	base := path.Base(file)
+	prefix := strings.TrimSuffix(base, ".go")
+	return strings.TrimPrefix(prefix, dirPrefix)
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/local/device/local_device_CurrentPropertyListMixIn.go
similarity index 65%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/local/device/local_device_CurrentPropertyListMixIn.go
index efbea52..936beb8 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/local/device/local_device_CurrentPropertyListMixIn.go
@@ -17,19 +17,7 @@
  * under the License.
  */
 
-package object
+package device
 
-import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
-
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
-}
-
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+type CurrentPropertyListMixIn struct {
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDevice.go b/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDevice.go
index dfa5d6a..8ff2d19 100644
--- a/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDevice.go
+++ b/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDevice.go
@@ -20,11 +20,38 @@
 package device
 
 import (
+	"fmt"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	"github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
 	readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 )
 
-//go:generate plc4xGenerator -type=LocalDeviceObject -prefix=local_device_
-type LocalDeviceObject struct {
+type LocalDeviceObject interface {
+	fmt.Stringer
+	GetObjectIdentifier() string
+	GetMaximumApduLengthAccepted() *readWriteModel.MaxApduLengthAccepted
+	GetSegmentationSupported() *readWriteModel.BACnetSegmentation
+	GetVendorIdentifier() any
+	GetNumberOfAPDURetries() *uint
+	GetAPDUTimeout() *uint
+	SetApp(a any)
+	GetAPDUSegmentTimeout() *uint
+	GetObjectName() string
+	GetMaxSegmentsAccepted() *readWriteModel.MaxSegmentsAccepted
+	GetObjectList() []string
+	SetObjectList([]string)
+}
+
+func NewLocalDeviceObject(args Args, kwArgs KWArgs) LocalDeviceObject {
+	return &localDeviceObject{}
+}
+
+type localDeviceObject struct {
+	*CurrentPropertyListMixIn
+	*object.DeviceObject
+
+	// TODO: replace below...
 	NumberOfAPDURetries       *uint
 	APDUTimeout               *uint
 	SegmentationSupported     *readWriteModel.BACnetSegmentation `directSerialize:"true"`
@@ -37,3 +64,55 @@
 	VendorIdentifier          uint16
 	ObjectList                []string
 }
+
+func (l *localDeviceObject) GetObjectIdentifier() string {
+	return l.ObjectIdentifier
+}
+
+func (l *localDeviceObject) GetMaximumApduLengthAccepted() *readWriteModel.MaxApduLengthAccepted {
+	return l.MaximumApduLengthAccepted
+}
+
+func (l *localDeviceObject) GetSegmentationSupported() *readWriteModel.BACnetSegmentation {
+	return l.SegmentationSupported
+}
+
+func (l *localDeviceObject) GetVendorIdentifier() any {
+	return l.VendorIdentifier
+}
+
+func (l *localDeviceObject) GetNumberOfAPDURetries() *uint {
+	return l.NumberOfAPDURetries
+}
+
+func (l *localDeviceObject) GetAPDUTimeout() *uint {
+	return l.APDUTimeout
+}
+
+func (l *localDeviceObject) SetApp(a any) {
+	l.App = a
+}
+
+func (l *localDeviceObject) GetAPDUSegmentTimeout() *uint {
+	return l.APDUSegmentTimeout
+}
+
+func (l *localDeviceObject) GetObjectName() string {
+	return l.ObjectName
+}
+
+func (l *localDeviceObject) GetMaxSegmentsAccepted() *readWriteModel.MaxSegmentsAccepted {
+	return l.MaxSegmentsAccepted
+}
+
+func (l *localDeviceObject) GetObjectList() []string {
+	return l.ObjectList
+}
+
+func (l *localDeviceObject) SetObjectList(strings []string) {
+	l.ObjectList = strings
+}
+
+func (l *localDeviceObject) String() string {
+	panic("implementme")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDeviceObject_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDeviceObject_plc4xgen.go
deleted file mode 100644
index 16c4ef6..0000000
--- a/plc4go/internal/bacnetip/bacgopes/local/device/local_device_LocalDeviceObject_plc4xgen.go
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// Code generated by "plc4xGenerator -type=LocalDeviceObject -prefix=local_device_"; DO NOT EDIT.
-
-package device
-
-import (
-	"context"
-	"encoding/binary"
-	"fmt"
-	"github.com/apache/plc4x/plc4go/spi/utils"
-)
-
-var _ = fmt.Printf
-
-func (d *LocalDeviceObject) Serialize() ([]byte, error) {
-	if d == nil {
-		return nil, fmt.Errorf("(*DeviceInfoCache)(nil)")
-	}
-	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
-	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
-		return nil, err
-	}
-	return wb.GetBytes(), nil
-}
-
-func (d *LocalDeviceObject) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
-	if d == nil {
-		return fmt.Errorf("(*DeviceInfoCache)(nil)")
-	}
-	if err := writeBuffer.PushContext("LocalDeviceObject"); err != nil {
-		return err
-	}
-	if d.NumberOfAPDURetries != nil {
-		{
-			_value := fmt.Sprintf("%v", d.NumberOfAPDURetries)
-
-			if err := writeBuffer.WriteString("numberOfAPDURetries", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
-		}
-	}
-	if d.APDUTimeout != nil {
-		{
-			_value := fmt.Sprintf("%v", d.APDUTimeout)
-
-			if err := writeBuffer.WriteString("aPDUTimeout", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
-		}
-	}
-	if d.SegmentationSupported != nil {
-		if err := writeBuffer.PushContext("segmentationSupported"); err != nil {
-			return err
-		}
-		if err := d.SegmentationSupported.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-			return err
-		}
-		if err := writeBuffer.PopContext("segmentationSupported"); err != nil {
-			return err
-		}
-	}
-	if d.APDUSegmentTimeout != nil {
-		{
-			_value := fmt.Sprintf("%v", d.APDUSegmentTimeout)
-
-			if err := writeBuffer.WriteString("aPDUSegmentTimeout", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
-		}
-	}
-	if d.MaxSegmentsAccepted != nil {
-		if err := writeBuffer.PushContext("maxSegmentsAccepted"); err != nil {
-			return err
-		}
-		if err := d.MaxSegmentsAccepted.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-			return err
-		}
-		if err := writeBuffer.PopContext("maxSegmentsAccepted"); err != nil {
-			return err
-		}
-	}
-	if d.MaximumApduLengthAccepted != nil {
-		if err := writeBuffer.PushContext("maximumApduLengthAccepted"); err != nil {
-			return err
-		}
-		if err := d.MaximumApduLengthAccepted.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-			return err
-		}
-		if err := writeBuffer.PopContext("maximumApduLengthAccepted"); err != nil {
-			return err
-		}
-	}
-
-	if err := writeBuffer.WriteString("objectName", uint32(len(d.ObjectName)*8), d.ObjectName); err != nil {
-		return err
-	}
-
-	if err := writeBuffer.WriteString("objectIdentifier", uint32(len(d.ObjectIdentifier)*8), d.ObjectIdentifier); err != nil {
-		return err
-	}
-
-	if err := writeBuffer.WriteUint16("vendorIdentifier", 16, d.VendorIdentifier); err != nil {
-		return err
-	}
-	if err := writeBuffer.PushContext("objectList", utils.WithRenderAsList(true)); err != nil {
-		return err
-	}
-	for _, elem := range d.ObjectList {
-		if err := writeBuffer.WriteString("", uint32(len(elem)*8), elem); err != nil {
-			return err
-		}
-	}
-	if err := writeBuffer.PopContext("objectList", utils.WithRenderAsList(true)); err != nil {
-		return err
-	}
-	if err := writeBuffer.PopContext("LocalDeviceObject"); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (d *LocalDeviceObject) String() string {
-	if alternateStringer, ok := any(d).(utils.AlternateStringer); ok {
-		if alternateString, use := alternateStringer.AlternateString(); use {
-			return alternateString
-		}
-	}
-	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
-	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
-		return err.Error()
-	}
-	return writeBuffer.GetBox().String()
-}
diff --git a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_NetworkServiceAccessPoint.go b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_NetworkServiceAccessPoint.go
index bca8eaa..642431c 100644
--- a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_NetworkServiceAccessPoint.go
+++ b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_NetworkServiceAccessPoint.go
@@ -230,7 +230,7 @@
 	n.log.Debug().Stringer("localAdapter", localAdapter).Msg("localAdapter")
 
 	// build a generic APDU
-	apdu, err := NewAPDU(nil, NKW(KWCPCIUserData, pdu.GetPDUUserData())) // Note: upstream makes a _APDU instance which looks like a programming error as this class is only useful in an extension context...
+	apdu, err := New_APDU(nil, NKW(KWCPCIUserData, pdu.GetPDUUserData())) // Note: upstream makes a _APDU instance which looks like a programming error as this class is only useful in an extension context...
 	if err != nil {
 		return errors.Wrap(err, "error creating _APDU")
 	}
@@ -351,7 +351,7 @@
 
 		// check the path status
 		dnetStatus := routerInfo.dnets[nk(dnet)]
-		n.log.Debug().Stringer("dnetStatus", dnetStatus).Msg("dnetStatus")
+		n.log.Debug().Interface("dnetStatus", dnetStatus).Msg("dnetStatus")
 
 		// fix the destination
 		npdu.SetPDUDestination(routerInfo.address)
@@ -462,7 +462,7 @@
 		if processLocally && n.HasServerPeer() {
 			n.log.Trace().Msg("processing APDU locally")
 			// decode as a generic APDU
-			apdu, err := NewAPDU(NoArgs, NKW(KWCPCIUserData, npdu.GetPDUUserData()))
+			apdu, err := New_APDU(NoArgs, NKW(KWCPCIUserData, npdu.GetPDUUserData()))
 			if err != nil {
 				return errors.Wrap(err, "error creating APDU")
 			}
@@ -675,7 +675,7 @@
 			}
 
 			// pass this along as if it came from the NSE
-			if err := n.SapIndication(NA(xadapter, NewPDU(NoArgs, NKW(KWCompRootMessage, xnpdu, KWCPCIDestination, pduDestination))), NoKWArgs()); err != nil {
+			if err := n.SapIndication(NA(xadapter, NewPDU(NoArgs, NKW(KWCPCIDestination, pduDestination), WithRootMessage(xnpdu))), NoKWArgs()); err != nil {
 				return errors.Wrap(err, "error sending indication")
 			}
 		}
diff --git a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfoCache.go b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfoCache.go
index 291796c..f97510c 100644
--- a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfoCache.go
+++ b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfoCache.go
@@ -23,6 +23,7 @@
 	"github.com/pkg/errors"
 	"github.com/rs/zerolog"
 
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
 )
 
@@ -59,7 +60,7 @@
 type RouterInfo struct {
 	snet    netKey   `stringer:"true"`
 	address *Address `stringer:"true"`
-	dnets   map[netKey]*RouterStatus
+	dnets   map[netKey]RouterStatus
 	status  RouterStatus `stringer:"true"`
 }
 
@@ -95,6 +96,9 @@
 }
 
 func (n *RouterInfoCache) UpdateRouterInfo(snet netKey, address *Address, dnets []uint16, status *RouterStatus) error {
+	if status == nil {
+		status = ToPtr(ROUTER_AVAILABLE)
+	}
 	n.log.Debug().Stringer("snet", snet).Stringer("dnet", address).Uints16("dnets", dnets).Msg("UpdateRouterInfo")
 
 	var existingRouterInfo *RouterInfo
@@ -134,7 +138,7 @@
 
 	// update current router info if there is one
 	if existingRouterInfo == nil {
-		routerInfo := &RouterInfo{snet: snet, address: address, dnets: make(map[netKey]*RouterStatus)}
+		routerInfo := &RouterInfo{snet: snet, address: address, dnets: make(map[netKey]RouterStatus)}
 		if _, ok := n.routers[snet]; !ok {
 			n.routers[snet] = &Router{addresses: map[string]*RouterInfo{
 				address.String(): routerInfo,
@@ -150,7 +154,7 @@
 				Uint16("dnet", dnet).
 				Stringer("routerInfoAddress", routerInfo.address).
 				Msg("add path: snet -> dnet via routerInfoAddress")
-			routerInfo.dnets[nk(&dnet)] = status
+			routerInfo.dnets[nk(&dnet)] = *status
 		}
 	} else {
 		for _, dnet := range dnets {
@@ -161,7 +165,7 @@
 					Uint16("dnet", dnet).
 					Msg("add path: snet -> dnet")
 			}
-			existingRouterInfo.dnets[nk(&dnet)] = status
+			existingRouterInfo.dnets[nk(&dnet)] = *status
 		}
 	}
 	return nil
diff --git a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfo_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfo_plc4xgen.go
index 0e96c25..82c7c04 100644
--- a/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfo_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/netservice/netservice_RouterInfo_plc4xgen.go
@@ -62,23 +62,10 @@
 	}
 	for _name, elem := range d.dnets {
 		name := fmt.Sprintf("%v", &_name)
+		_value := fmt.Sprintf("%v", elem)
 
-		var elem any = elem
-		if serializable, ok := elem.(utils.Serializable); ok {
-			if err := writeBuffer.PushContext(name); err != nil {
-				return err
-			}
-			if err := serializable.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
-				return err
-			}
-			if err := writeBuffer.PopContext(name); err != nil {
-				return err
-			}
-		} else {
-			elemAsString := fmt.Sprintf("%v", elem)
-			if err := writeBuffer.WriteString(name, uint32(len(elemAsString)*8), elemAsString); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString(name, uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if err := writeBuffer.PopContext("dnets", utils.WithRenderAsList(true)); err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_DisconnectConnectionToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_DisconnectConnectionToNetwork.go
index 1d61ca9..7906d96 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_DisconnectConnectionToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_DisconnectConnectionToNetwork.go
@@ -37,17 +37,14 @@
 	dctnDNET uint16
 }
 
-func NewDisconnectConnectionToNetwork(args Args, kwArgs KWArgs, opts ...func(*DisconnectConnectionToNetwork)) (*DisconnectConnectionToNetwork, error) {
+func NewDisconnectConnectionToNetwork(args Args, kwArgs KWArgs, options ...Option) (*DisconnectConnectionToNetwork, error) {
 	i := &DisconnectConnectionToNetwork{
 		messageType: 0x09,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMDisconnectConnectionToNetwork(i.dctnDNET, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMDisconnectConnectionToNetwork(i.dctnDNET, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -57,10 +54,9 @@
 	return i, nil
 }
 
-func WithDisconnectConnectionToNetworkDNET(dnet uint16) func(*DisconnectConnectionToNetwork) {
-	return func(n *DisconnectConnectionToNetwork) {
-		n.dctnDNET = dnet
-	}
+// TODO: check if this is rather a KWArgs
+func WithDisconnectConnectionToNetworkDNET(dnet uint16) GenericApplier[*DisconnectConnectionToNetwork] {
+	return WrapGenericApplier(func(n *DisconnectConnectionToNetwork) { n.dctnDNET = dnet })
 }
 
 func (n *DisconnectConnectionToNetwork) GetDctnDNET() uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_EstablishConnectionToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_EstablishConnectionToNetwork.go
index aec813d..2f83a5f 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_EstablishConnectionToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_EstablishConnectionToNetwork.go
@@ -38,65 +38,60 @@
 	ectnTerminationTime uint8
 }
 
-func NewEstablishConnectionToNetwork(args Args, kwArgs KWArgs, opts ...func(*EstablishConnectionToNetwork)) (*EstablishConnectionToNetwork, error) {
-	i := &EstablishConnectionToNetwork{
+func NewEstablishConnectionToNetwork(args Args, kwArgs KWArgs, options ...Option) (*EstablishConnectionToNetwork, error) {
+	e := &EstablishConnectionToNetwork{
 		messageType: 0x08,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMEstablishConnectionToNetwork(i.ectnDNET, i.ectnTerminationTime, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, e)
+	options = AddLeafTypeIfAbundant(options, e)
+	options = AddNLMIfAbundant(options, model.NewNLMEstablishConnectionToNetwork(e.ectnDNET, e.ectnTerminationTime, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
-	i._NPDU = npdu.(*_NPDU)
+	e._NPDU = npdu.(*_NPDU)
 
-	i.npduNetMessage = &i.messageType
-	return i, nil
+	e.npduNetMessage = &e.messageType
+	return e, nil
 }
 
-func WithEstablishConnectionToNetworkDNET(dnet uint16) func(*EstablishConnectionToNetwork) {
-	return func(n *EstablishConnectionToNetwork) {
-		n.ectnDNET = dnet
-	}
+// TODO: check if this is rather a KWArgs
+func WithEstablishConnectionToNetworkDNET(dnet uint16) GenericApplier[*EstablishConnectionToNetwork] {
+	return WrapGenericApplier(func(n *EstablishConnectionToNetwork) { n.ectnDNET = dnet })
 }
 
-func WithEstablishConnectionToNetworkTerminationTime(terminationTime uint8) func(*EstablishConnectionToNetwork) {
-	return func(n *EstablishConnectionToNetwork) {
-		n.ectnTerminationTime = terminationTime
-	}
+// TODO: check if this is rather a KWArgs
+func WithEstablishConnectionToNetworkTerminationTime(terminationTime uint8) GenericApplier[*EstablishConnectionToNetwork] {
+	return WrapGenericApplier(func(n *EstablishConnectionToNetwork) { n.ectnTerminationTime = terminationTime })
 }
 
-func (n *EstablishConnectionToNetwork) GetEctnDNET() uint16 {
-	return n.ectnDNET
+func (e *EstablishConnectionToNetwork) GetEctnDNET() uint16 {
+	return e.ectnDNET
 }
 
-func (n *EstablishConnectionToNetwork) GetEctnTerminationTime() uint8 {
-	return n.ectnTerminationTime
+func (e *EstablishConnectionToNetwork) GetEctnTerminationTime() uint8 {
+	return e.ectnTerminationTime
 }
 
-func (n *EstablishConnectionToNetwork) Encode(npdu Arg) error {
+func (e *EstablishConnectionToNetwork) Encode(npdu Arg) error {
 	switch npdu := npdu.(type) {
 	case NPCI:
-		if err := npdu.GetNPCI().Update(n); err != nil {
+		if err := npdu.GetNPCI().Update(e); err != nil {
 			return errors.Wrap(err, "error updating NPDU")
 		}
 	}
 	switch npdu := npdu.(type) {
 	case PDUData:
-		npdu.PutShort(n.ectnDNET)
-		npdu.Put(n.ectnTerminationTime)
+		npdu.PutShort(e.ectnDNET)
+		npdu.Put(e.ectnTerminationTime)
 	default:
 		return errors.Errorf("invalid NPDU type %T", npdu)
 	}
 	return nil
 }
 
-func (n *EstablishConnectionToNetwork) Decode(npdu Arg) error {
-	if err := n._NPCI.Update(npdu); err != nil {
+func (e *EstablishConnectionToNetwork) Decode(npdu Arg) error {
+	if err := e._NPCI.Update(npdu); err != nil {
 		return errors.Wrap(err, "error updating NPCI")
 	}
 	switch npdu := npdu.(type) {
@@ -105,19 +100,19 @@
 		case model.NPDU:
 			switch nlm := rm.GetNlm().(type) {
 			case model.NLMEstablishConnectionToNetwork:
-				n.ectnDNET = nlm.GetDestinationNetworkAddress()
-				n.ectnTerminationTime = nlm.GetTerminationTime()
-				n.SetRootMessage(rm)
+				e.ectnDNET = nlm.GetDestinationNetworkAddress()
+				e.ectnTerminationTime = nlm.GetTerminationTime()
+				e.SetRootMessage(rm)
 			}
 		}
 	}
 	switch npdu := npdu.(type) {
 	case PDUData:
-		n.SetPduData(npdu.GetPduData())
+		e.SetPduData(npdu.GetPduData())
 	}
 	return nil
 }
 
-func (n *EstablishConnectionToNetwork) String() string {
-	return fmt.Sprintf("EstablishConnectionToNetwork{%s, ectnDNET: %v, ectnTerminationTime: %v}", n._NPDU, n.ectnDNET, n.ectnTerminationTime)
+func (e *EstablishConnectionToNetwork) String() string {
+	return fmt.Sprintf("EstablishConnectionToNetwork{%s, ectnDNET: %v, ectnTerminationTime: %v}", e._NPDU, e.ectnDNET, e.ectnTerminationTime)
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_IAmRouterToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_IAmRouterToNetwork.go
index 629464b..8f1f691 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_IAmRouterToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_IAmRouterToNetwork.go
@@ -37,17 +37,14 @@
 	iartnNetworkList []uint16
 }
 
-func NewIAmRouterToNetwork(args Args, kwArgs KWArgs, opts ...func(*IAmRouterToNetwork)) (*IAmRouterToNetwork, error) {
+func NewIAmRouterToNetwork(args Args, kwArgs KWArgs, options ...Option) (*IAmRouterToNetwork, error) {
 	i := &IAmRouterToNetwork{
 		messageType: 0x01,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMIAmRouterToNetwork(i.iartnNetworkList, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMIAmRouterToNetwork(i.iartnNetworkList, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -57,10 +54,9 @@
 	return i, nil
 }
 
-func WithIAmRouterToNetworkNetworkList(iartnNetworkList ...uint16) func(*IAmRouterToNetwork) {
-	return func(n *IAmRouterToNetwork) {
-		n.iartnNetworkList = iartnNetworkList
-	}
+// TODO: check if this is rather a KWArgs
+func WithIAmRouterToNetworkNetworkList(iartnNetworkList ...uint16) GenericApplier[*IAmRouterToNetwork] {
+	return WrapGenericApplier(func(n *IAmRouterToNetwork) { n.iartnNetworkList = iartnNetworkList })
 }
 
 func (i *IAmRouterToNetwork) GetIartnNetworkList() []uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_ICouldBeRouterToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_ICouldBeRouterToNetwork.go
index 36943db..17bbc4e 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_ICouldBeRouterToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_ICouldBeRouterToNetwork.go
@@ -38,17 +38,14 @@
 	icbrtnPerformanceIndex uint8
 }
 
-func NewICouldBeRouterToNetwork(args Args, kwArgs KWArgs, opts ...func(*ICouldBeRouterToNetwork)) (*ICouldBeRouterToNetwork, error) {
+func NewICouldBeRouterToNetwork(args Args, kwArgs KWArgs, options ...Option) (*ICouldBeRouterToNetwork, error) {
 	i := &ICouldBeRouterToNetwork{
 		messageType: 0x02,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMICouldBeRouterToNetwork(i.icbrtnNetwork, i.icbrtnPerformanceIndex, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMICouldBeRouterToNetwork(i.icbrtnNetwork, i.icbrtnPerformanceIndex, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -58,16 +55,14 @@
 	return i, nil
 }
 
-func WithICouldBeRouterToNetworkNetwork(icbrtnNetwork uint16) func(*ICouldBeRouterToNetwork) {
-	return func(n *ICouldBeRouterToNetwork) {
-		n.icbrtnNetwork = icbrtnNetwork
-	}
+// TODO: check if this is rather a KWArgs
+func WithICouldBeRouterToNetworkNetwork(icbrtnNetwork uint16) GenericApplier[*ICouldBeRouterToNetwork] {
+	return WrapGenericApplier(func(n *ICouldBeRouterToNetwork) { n.icbrtnNetwork = icbrtnNetwork })
 }
 
-func WithICouldBeRouterToNetworkPerformanceIndex(icbrtnPerformanceIndex uint8) func(*ICouldBeRouterToNetwork) {
-	return func(n *ICouldBeRouterToNetwork) {
-		n.icbrtnPerformanceIndex = icbrtnPerformanceIndex
-	}
+// TODO: check if this is rather a KWArgs
+func WithICouldBeRouterToNetworkPerformanceIndex(icbrtnPerformanceIndex uint8) GenericApplier[*ICouldBeRouterToNetwork] {
+	return WrapGenericApplier(func(n *ICouldBeRouterToNetwork) { n.icbrtnPerformanceIndex = icbrtnPerformanceIndex })
 }
 
 func (i *ICouldBeRouterToNetwork) GetIcbrtnNetwork() uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTable.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTable.go
index 20b2b44..12c60a4 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTable.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTable.go
@@ -37,17 +37,14 @@
 	irtTable []*RoutingTableEntry
 }
 
-func NewInitializeRoutingTable(args Args, kwArgs KWArgs, opts ...func(*InitializeRoutingTable)) (*InitializeRoutingTable, error) {
+func NewInitializeRoutingTable(args Args, kwArgs KWArgs, options ...Option) (*InitializeRoutingTable, error) {
 	i := &InitializeRoutingTable{
 		messageType: 0x06,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMInitializeRoutingTable(i.produceNLMInitializeRoutingTablePortMapping())
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMInitializeRoutingTable(i.produceNLMInitializeRoutingTablePortMapping()))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -57,10 +54,9 @@
 	return i, nil
 }
 
-func WithInitializeRoutingTableIrtTable(irtTable ...*RoutingTableEntry) func(*InitializeRoutingTable) {
-	return func(r *InitializeRoutingTable) {
-		r.irtTable = irtTable
-	}
+// TODO: check if this is rather a KWArgs
+func WithInitializeRoutingTableIrtTable(irtTable ...*RoutingTableEntry) GenericApplier[*InitializeRoutingTable] {
+	return WrapGenericApplier(func(r *InitializeRoutingTable) { r.irtTable = irtTable })
 }
 
 func (i *InitializeRoutingTable) GetIrtTable() []*RoutingTableEntry {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTableAck.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTableAck.go
index 2db11b2..0f20096 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTableAck.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_InitializeRoutingTableAck.go
@@ -37,17 +37,14 @@
 	irtaTable []*RoutingTableEntry
 }
 
-func NewInitializeRoutingTableAck(args Args, kwArgs KWArgs, opts ...func(*InitializeRoutingTableAck)) (*InitializeRoutingTableAck, error) {
+func NewInitializeRoutingTableAck(args Args, kwArgs KWArgs, options ...Option) (*InitializeRoutingTableAck, error) {
 	i := &InitializeRoutingTableAck{
 		messageType: 0x07,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMInitializeRoutingTableAck(i.produceNLMInitializeRoutingTableAckPortMapping())
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMInitializeRoutingTableAck(i.produceNLMInitializeRoutingTableAckPortMapping()))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -57,10 +54,9 @@
 	return i, nil
 }
 
-func WithInitializeRoutingTableAckIrtaTable(irtaTable ...*RoutingTableEntry) func(*InitializeRoutingTableAck) {
-	return func(r *InitializeRoutingTableAck) {
-		r.irtaTable = irtaTable
-	}
+// TODO: check if this is rather a KWArgs
+func WithInitializeRoutingTableAckIrtaTable(irtaTable ...*RoutingTableEntry) GenericApplier[*InitializeRoutingTableAck] {
+	return WrapGenericApplier(func(r *InitializeRoutingTableAck) { r.irtaTable = irtaTable })
 }
 
 func (i *InitializeRoutingTableAck) GetIrtaTable() []*RoutingTableEntry {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPCI.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPCI.go
index 8979306..8886633 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPCI.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPCI.go
@@ -77,18 +77,19 @@
 
 var _ NPCI = (*_NPCI)(nil)
 
-func NewNPCI(args Args, kwArgs KWArgs) NPCI {
+func NewNPCI(args Args, kwArgs KWArgs, options ...Option) NPCI {
 	n := &_NPCI{
 		npduVersion: 1,
 	}
 	n.DebugContents = NewDebugContents(n, "npduVersion", "npduControl", "npduDADR", "npduSADR",
 		"npduHopCount", "npduNetMessage", "npduVendorID")
-	n.PCI = NewPCI(args, kwArgs)
+	options = AddLeafTypeIfAbundant(options, n)
+	n.PCI = NewPCI(args, kwArgs, options...)
 	n.AddExtraPrinters(n.PCI.(DebugContentPrinter))
 	if n.GetRootMessage() == nil {
-		nlm, nlmOk := KWO[readWriteModel.NLM](kwArgs, KWCompNLM, nil)
-		apdu, apduOk := KWO[readWriteModel.APDU](kwArgs, KWCompAPDU, nil)
-		if nlmOk || apduOk {
+		nlm := ExtractNLM(options)
+		apdu := ExtractAPDU(options)
+		if nlm != nil || apdu != nil {
 			npdu, _ := n.buildNPDU(0, nil, nil, false, readWriteModel.NPDUNetworkPriority_NORMAL_MESSAGE, nlm, apdu)
 			n.SetRootMessage(npdu)
 		}
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPDU.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPDU.go
index 9944770..ed46991 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NPDU.go
@@ -47,10 +47,11 @@
 
 var _ = (NPDU)(nil)
 
-func NewNPDU(args Args, kwArgs KWArgs) (NPDU, error) {
+func NewNPDU(args Args, kwArgs KWArgs, options ...Option) (NPDU, error) {
 	n := &_NPDU{}
-	n._NPCI = NewNPCI(args, kwArgs).(*_NPCI)
-	n.PDUData = NewPDUData(NoArgs, NoKWArgs())
+	options = AddLeafTypeIfAbundant(options, n)
+	n._NPCI = NewNPCI(args, kwArgs, options...).(*_NPCI)
+	n.PDUData = NewPDUData(NoArgs, NoKWArgs(), options...)
 	n.AddExtraPrinters(n.PDUData.(DebugContentPrinter))
 	if n.GetRootMessage() != nil {
 		data, _ := n.GetRootMessage().Serialize()
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NetworkNumberIs.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NetworkNumberIs.go
index e269369..5191f26 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NetworkNumberIs.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_NetworkNumberIs.go
@@ -38,17 +38,14 @@
 	nniFlag bool
 }
 
-func NewNetworkNumberIs(args Args, kwArgs KWArgs, opts ...func(*NetworkNumberIs)) (*NetworkNumberIs, error) {
+func NewNetworkNumberIs(args Args, kwArgs KWArgs, options ...Option) (*NetworkNumberIs, error) {
 	n := &NetworkNumberIs{
 		messageType: 0x13,
 	}
-	for _, opt := range opts {
-		opt(n)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMNetworkNumberIs(n.nniNet, n.nniFlag, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, n)
+	options = AddLeafTypeIfAbundant(options, n)
+	options = AddNLMIfAbundant(options, model.NewNLMNetworkNumberIs(n.nniNet, n.nniFlag, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -58,16 +55,14 @@
 	return n, nil
 }
 
-func WithNetworkNumberIsNET(net uint16) func(*NetworkNumberIs) {
-	return func(n *NetworkNumberIs) {
-		n.nniNet = net
-	}
+// TODO: check if this is rather a KWArgs
+func WithNetworkNumberIsNET(net uint16) GenericApplier[*NetworkNumberIs] {
+	return WrapGenericApplier(func(n *NetworkNumberIs) { n.nniNet = net })
 }
 
-func WithNetworkNumberIsTerminationConfigured(configured bool) func(*NetworkNumberIs) {
-	return func(n *NetworkNumberIs) {
-		n.nniFlag = configured
-	}
+// TODO: check if this is rather a KWArgs
+func WithNetworkNumberIsTerminationConfigured(configured bool) GenericApplier[*NetworkNumberIs] {
+	return WrapGenericApplier(func(n *NetworkNumberIs) { n.nniFlag = configured })
 }
 
 func (n *NetworkNumberIs) GetNniNet() uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RejectMessageToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RejectMessageToNetwork.go
index 013ff40..c0402f3 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RejectMessageToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RejectMessageToNetwork.go
@@ -38,17 +38,14 @@
 	rmtnDNET            uint16
 }
 
-func NewRejectMessageToNetwork(args Args, kwArgs KWArgs, opts ...func(*RejectMessageToNetwork)) (*RejectMessageToNetwork, error) {
+func NewRejectMessageToNetwork(args Args, kwArgs KWArgs, options ...Option) (*RejectMessageToNetwork, error) {
 	i := &RejectMessageToNetwork{
 		messageType: 0x03,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMRejectMessageToNetwork(i.rmtnRejectionReason, i.rmtnDNET, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMRejectMessageToNetwork(i.rmtnRejectionReason, i.rmtnDNET, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -58,16 +55,14 @@
 	return i, nil
 }
 
-func WithRejectMessageToNetworkRejectionReason(reason model.NLMRejectMessageToNetworkRejectReason) func(*RejectMessageToNetwork) {
-	return func(n *RejectMessageToNetwork) {
-		n.rmtnRejectionReason = reason
-	}
+// TODO: check if this is rather a KWArgs
+func WithRejectMessageToNetworkRejectionReason(reason model.NLMRejectMessageToNetworkRejectReason) GenericApplier[*RejectMessageToNetwork] {
+	return WrapGenericApplier(func(n *RejectMessageToNetwork) { n.rmtnRejectionReason = reason })
 }
 
-func WithRejectMessageToNetworkDnet(dnet uint16) func(*RejectMessageToNetwork) {
-	return func(n *RejectMessageToNetwork) {
-		n.rmtnDNET = dnet
-	}
+// TODO: check if this is rather a KWArgs
+func WithRejectMessageToNetworkDnet(dnet uint16) GenericApplier[*RejectMessageToNetwork] {
+	return WrapGenericApplier(func(n *RejectMessageToNetwork) { n.rmtnDNET = dnet })
 }
 
 func (r *RejectMessageToNetwork) GetRmtnRejectionReason() model.NLMRejectMessageToNetworkRejectReason {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterAvailableToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterAvailableToNetwork.go
index 7db1061..05aed9f 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterAvailableToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterAvailableToNetwork.go
@@ -37,30 +37,26 @@
 	ratnNetworkList []uint16
 }
 
-func NewRouterAvailableToNetwork(args Args, kwArgs KWArgs, opts ...func(*RouterAvailableToNetwork)) (*RouterAvailableToNetwork, error) {
-	i := &RouterAvailableToNetwork{
+func NewRouterAvailableToNetwork(args Args, kwArgs KWArgs, options ...Option) (*RouterAvailableToNetwork, error) {
+	r := &RouterAvailableToNetwork{
 		messageType: 0x05,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMRouterAvailableToNetwork(i.ratnNetworkList, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, r)
+	options = AddLeafTypeIfAbundant(options, r)
+	options = AddNLMIfAbundant(options, model.NewNLMRouterAvailableToNetwork(r.ratnNetworkList, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
-	i._NPDU = npdu.(*_NPDU)
+	r._NPDU = npdu.(*_NPDU)
 
-	i.npduNetMessage = &i.messageType
-	return i, nil
+	r.npduNetMessage = &r.messageType
+	return r, nil
 }
 
-func WithRouterAvailableToNetworkDnet(networkList []uint16) func(*RouterAvailableToNetwork) {
-	return func(n *RouterAvailableToNetwork) {
-		n.ratnNetworkList = networkList
-	}
+// TODO: check if this is rather a KWArgs
+func WithRouterAvailableToNetworkDnet(networkList []uint16) GenericApplier[*RouterAvailableToNetwork] {
+	return WrapGenericApplier(func(n *RouterAvailableToNetwork) { n.ratnNetworkList = networkList })
 }
 
 func (r *RouterAvailableToNetwork) GetRatnNetworkList() []uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterBusyToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterBusyToNetwork.go
index 9de984e..e2744c9 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterBusyToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_RouterBusyToNetwork.go
@@ -37,30 +37,26 @@
 	rbtnNetworkList []uint16
 }
 
-func NewRouterBusyToNetwork(args Args, kwArgs KWArgs, opts ...func(*RouterBusyToNetwork)) (*RouterBusyToNetwork, error) {
-	i := &RouterBusyToNetwork{
+func NewRouterBusyToNetwork(args Args, kwArgs KWArgs, options ...Option) (*RouterBusyToNetwork, error) {
+	r := &RouterBusyToNetwork{
 		messageType: 0x04,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMRouterBusyToNetwork(i.rbtnNetworkList, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, r)
+	options = AddLeafTypeIfAbundant(options, r)
+	options = AddNLMIfAbundant(options, model.NewNLMRouterBusyToNetwork(r.rbtnNetworkList, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
-	i._NPDU = npdu.(*_NPDU)
+	r._NPDU = npdu.(*_NPDU)
 
-	i.npduNetMessage = &i.messageType
-	return i, nil
+	r.npduNetMessage = &r.messageType
+	return r, nil
 }
 
-func WithRouterBusyToNetworkDnet(networkList []uint16) func(*RouterBusyToNetwork) {
-	return func(n *RouterBusyToNetwork) {
-		n.rbtnNetworkList = networkList
-	}
+// TODO: check if this is rather a KWArgs
+func WithRouterBusyToNetworkDnet(networkList []uint16) GenericApplier[*RouterBusyToNetwork] {
+	return WrapGenericApplier(func(n *RouterBusyToNetwork) { n.rbtnNetworkList = networkList })
 }
 
 func (r *RouterBusyToNetwork) GetRbtnNetworkList() []uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhatIsNetworkNumber.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhatIsNetworkNumber.go
index 5d48540..6bf676f 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhatIsNetworkNumber.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhatIsNetworkNumber.go
@@ -35,17 +35,14 @@
 	messageType uint8
 }
 
-func NewWhatIsNetworkNumber(args Args, kwArgs KWArgs, opts ...func(*WhatIsNetworkNumber)) (*WhatIsNetworkNumber, error) {
+func NewWhatIsNetworkNumber(args Args, kwArgs KWArgs, options ...Option) (*WhatIsNetworkNumber, error) {
 	i := &WhatIsNetworkNumber{
 		messageType: 0x12,
 	}
-	for _, opt := range opts {
-		opt(i)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMWhatIsNetworkNumber(0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, i)
+	options = AddLeafTypeIfAbundant(options, i)
+	options = AddNLMIfAbundant(options, model.NewNLMWhatIsNetworkNumber(0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhoIsRouterToNetwork.go b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhoIsRouterToNetwork.go
index b11fff9..510c736 100644
--- a/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhoIsRouterToNetwork.go
+++ b/plc4go/internal/bacnetip/bacgopes/npdu/npdu_WhoIsRouterToNetwork.go
@@ -37,17 +37,14 @@
 	wirtnNetwork *uint16
 }
 
-func NewWhoIsRouterToNetwork(args Args, kwArgs KWArgs, opts ...func(network *WhoIsRouterToNetwork)) (*WhoIsRouterToNetwork, error) {
+func NewWhoIsRouterToNetwork(args Args, kwArgs KWArgs, options ...Option) (*WhoIsRouterToNetwork, error) {
 	w := &WhoIsRouterToNetwork{
 		messageType: 0x00,
 	}
-	for _, opt := range opts {
-		opt(w)
-	}
-	if _, ok := kwArgs[KWCompNLM]; ok {
-		kwArgs[KWCompNLM] = model.NewNLMWhoIsRouterToNetwork(w.wirtnNetwork, 0)
-	}
-	npdu, err := NewNPDU(args, kwArgs)
+	ApplyAppliers(options, w)
+	options = AddLeafTypeIfAbundant(options, w)
+	options = AddNLMIfAbundant(options, model.NewNLMWhoIsRouterToNetwork(w.wirtnNetwork, 0))
+	npdu, err := NewNPDU(args, kwArgs, options...)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating NPDU")
 	}
@@ -57,10 +54,8 @@
 	return w, nil
 }
 
-func WithWhoIsRouterToNetworkNet(net uint16) func(*WhoIsRouterToNetwork) {
-	return func(n *WhoIsRouterToNetwork) {
-		n.wirtnNetwork = &net
-	}
+func WithWhoIsRouterToNetworkNet(net uint16) GenericApplier[*WhoIsRouterToNetwork] {
+	return WrapGenericApplier(func(n *WhoIsRouterToNetwork) { n.wirtnNetwork = &net })
 }
 
 func (w *WhoIsRouterToNetwork) GetWirtnNetwork() *uint16 {
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object.go b/plc4go/internal/bacnetip/bacgopes/object/object.go
index d149cf7..8f7b6d0 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object.go
@@ -17,4 +17,62 @@
  * under the License.
  */
 
+// TODO: big WIP
 package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
+)
+
+var _debug = CreateDebugPrinter()
+
+var registeredObjectTypes map[any]struct{}
+
+func init() {
+	registeredObjectTypes = make(map[any]struct{})
+}
+
+// V2P accepts a function which takes an Arg and maps it to a PropertyKlass
+func V2P[T any](b func(arg Arg) (*T, error)) func(Args, KWArgs) (PropertyKlass, error) {
+	return func(args Args, kwArgs KWArgs) (PropertyKlass, error) {
+		var arg any
+		if len(args) == 1 {
+			arg = args[0]
+		}
+		r, err := b(arg)
+		return any(r).(PropertyKlass), err
+	}
+}
+
+// Vs2P accepts a function which takes an Args and maps it to a PropertyKlass
+func Vs2P[T any](b func(args Args) (*T, error)) func(Args, KWArgs) (PropertyKlass, error) {
+	return func(args Args, kwArgs KWArgs) (PropertyKlass, error) {
+		r, err := b(args)
+		return any(r).(PropertyKlass), err
+	}
+}
+
+// TODO: finish
+func SequenceOfP[T any](b func(arg Arg) (*T, error)) func(Args, KWArgs) (PropertyKlass, error) {
+	panic("finish me")
+}
+
+func SequenceOfsP[T any](b func(args Args) (*T, error)) func(Args, KWArgs) (PropertyKlass, error) {
+	panic("finish me")
+}
+
+// TODO: finish // convert to kwArgs and check wtf we are doing here...
+func ArrayOfP[T any](b func(arg Arg) (*T, error), fixedLength int, prototype any) func(Args, KWArgs) (PropertyKlass, error) {
+	panic("finish me")
+}
+
+// TODO: finish // convert to kwArgs and check wtf we are doing here...
+func ArrayOfsP[T any](b func(args Args) (*T, error), fixedLength int, prototype any) func(Args, KWArgs) (PropertyKlass, error) {
+	panic("finish me")
+}
+
+// TODO: finish // convert to kwArgs and check wtf we are doing here...
+func ListOfP[T any](b func(arg Arg) (*T, error)) func(Args, KWArgs) (PropertyKlass, error) {
+	panic("finish me")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessCredentialObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessCredentialObject.go
new file mode 100644
index 0000000..b69565e
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessCredentialObject.go
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessCredentialObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessCredentialObject(arg Arg) (*AccessCredentialObject, error) {
+	o := &AccessCredentialObject{
+		objectType: "accessCredential",
+		properties: []Property{
+			NewWritableProperty("globalIdentifier", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("credentialStatus", V2P(NewBinaryPV)),
+			NewReadableProperty("reasonForDisable", ListOfP(NewAccessCredentialDisableReason)),
+			NewReadableProperty("authenticationFactors", ArrayOfP(NewCredentialAuthenticationFactor, 0, 0)),
+			NewReadableProperty("activationTime", V2P(NewDateTime)),
+			NewReadableProperty("expirationTime", V2P(NewDateTime)),
+			NewReadableProperty("credentialDisable", V2P(NewAccessCredentialDisable)),
+			NewOptionalProperty("daysRemaining", V2P(NewInteger)),
+			NewOptionalProperty("usesRemaining", V2P(NewInteger)),
+			NewOptionalProperty("absenteeLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("belongsTo", V2P(NewDeviceObjectReference)),
+			NewReadableProperty("assignedAccessRights", ArrayOfP(NewAssignedAccessRights, 0, 0)),
+			NewOptionalProperty("lastAccessPoint", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("lastAccessEvent", V2P(NewAccessEvent)),
+			NewOptionalProperty("lastUseTime", V2P(NewDateTime)),
+			NewOptionalProperty("traceFlag", V2P(NewBoolean)),
+			NewOptionalProperty("threatAuthority", V2P(NewAccessThreatLevel)),
+			NewOptionalProperty("extendedTimeEnable", V2P(NewBoolean)),
+			NewOptionalProperty("authorizationExemptions", ListOfP(NewAuthorizationException)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			//       , NewOptionalProperty("masterExemption", V2P(NewBoolean)
+			//       , NewOptionalProperty("passbackExemption", V2P(NewBoolean)
+			//       , NewOptionalProperty("occupancyExemption", V2P(NewBoolean)
+		},
+	}
+	return o, nil
+}
+
+// TODO: @register_object_type
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessDoorObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessDoorObject.go
new file mode 100644
index 0000000..e471528
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessDoorObject.go
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessDoorObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessDoorObject(arg Arg) (*AccessDoorObject, error) {
+	o := &AccessDoorObject{
+		objectType:           "accessDoor",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewDoorValue)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewReadableProperty("relinquishDefault", V2P(NewDoorValue)),
+			NewOptionalProperty("doorStatus", V2P(NewDoorStatus)),
+			NewOptionalProperty("lockStatus", V2P(NewLockStatus)),
+			NewOptionalProperty("securedStatus", V2P(NewDoorSecuredStatus)),
+			NewOptionalProperty("doorMembers", ArrayOfP(NewDeviceObjectReference, 0, 0)),
+			NewReadableProperty("doorPulseTime", V2P(NewUnsigned)),
+			NewReadableProperty("doorExtendedPulseTime", V2P(NewUnsigned)),
+			NewOptionalProperty("doorUnlockDelayTime", V2P(NewUnsigned)),
+			NewReadableProperty("doorOpenTooLongTime", V2P(NewUnsigned)),
+			NewOptionalProperty("doorAlarmState", V2P(NewDoorAlarmState)),
+			NewOptionalProperty("maskedAlarmValues", ListOfP(NewDoorAlarmState)),
+			NewOptionalProperty("maintenanceRequired", V2P(NewMaintenance)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ListOfP(NewDoorAlarmState)),
+			NewOptionalProperty("faultValues", ListOfP(NewDoorAlarmState)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	return o, nil
+}
+
+// TODO: @register_object_type
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessPointObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessPointObject.go
new file mode 100644
index 0000000..02bc1c6
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessPointObject.go
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessPointObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessPointObject(arg Arg) (*AccessPointObject, error) {
+	o := &AccessPointObject{
+		objectType:           "accessPoint",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("authenticationStatus", V2P(NewAuthenticationStatus)),
+			NewReadableProperty("activeAuthenticationPolicy", V2P(NewUnsigned)),
+			NewReadableProperty("numberOfAuthenticationPolicies", V2P(NewUnsigned)),
+			NewOptionalProperty("authenticationPolicyList", ArrayOfP(NewAuthenticationPolicy, 0, 0)),
+			NewOptionalProperty("authenticationPolicyNames", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("authorizationMode", V2P(NewAuthorizationMode)),
+			NewOptionalProperty("verificationTime", V2P(NewUnsigned)),
+			NewOptionalProperty("lockout", V2P(NewBoolean)),
+			NewOptionalProperty("lockoutRelinquishTime", V2P(NewUnsigned)),
+			NewOptionalProperty("failedAttempts", V2P(NewUnsigned)),
+			NewOptionalProperty("failedAttemptEvents", ListOfP(NewAccessEvent)),
+			NewOptionalProperty("maxFailedAttempts", V2P(NewUnsigned)),
+			NewOptionalProperty("failedAttemptsTime", V2P(NewUnsigned)),
+			NewOptionalProperty("threatLevel", V2P(NewAccessThreatLevel)),
+			NewOptionalProperty("occupancyUpperLimitEnforced", V2P(NewBoolean)),
+			NewOptionalProperty("occupancyLowerLimitEnforced", V2P(NewBoolean)),
+			NewOptionalProperty("occupancyCountAdjust", V2P(NewBoolean)),
+			NewOptionalProperty("accompanimentTime", V2P(NewUnsigned)),
+			NewReadableProperty("accessEvent", V2P(NewAccessEvent)),
+			NewReadableProperty("accessEventTag", V2P(NewUnsigned)),
+			NewReadableProperty("accessEventTime", V2P(NewTimeStamp)),
+			NewReadableProperty("accessEventCredential", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("accessEventAuthenticationFactor", V2P(NewAuthenticationFactor)),
+			NewReadableProperty("accessDoors", ArrayOfP(NewDeviceObjectReference, 0, 0)),
+			NewReadableProperty("priorityForWriting", V2P(NewUnsigned)),
+			NewOptionalProperty("musterPoint", V2P(NewBoolean)),
+			NewOptionalProperty("zoneTo", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("zoneFrom", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("transactionNotificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("accessAlarmEvents", ListOfP(NewAccessEvent)),
+			NewOptionalProperty("accessTransactionEvents", ListOfP(NewAccessEvent)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	return o, nil
+}
+
+// TODO: @register_object_type
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessRightsObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessRightsObject.go
new file mode 100644
index 0000000..bc65f09
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessRightsObject.go
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessRightsObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessRightsObject(arg Arg) (*AccessRightsObject, error) {
+	o := &AccessRightsObject{
+		objectType: "accessRights",
+		properties: []Property{
+			NewWritableProperty("globalIdentifier", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("enable", V2P(NewBoolean)),
+			NewReadableProperty("negativeAccessRules", ArrayOfP(NewAccessRule, 0, 0)),
+			NewReadableProperty("positiveAccessRules", ArrayOfP(NewAccessRule, 0, 0)),
+			NewOptionalProperty("accompaniment", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	return o, nil
+}
+
+// TODO: @register_object_type
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessUserObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessUserObject.go
new file mode 100644
index 0000000..a07e439
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessUserObject.go
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessUserObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessUserObject(arg Arg) (*AccessUserObject, error) {
+	o := &AccessUserObject{
+		objectType: "accessUser",
+		properties: []Property{
+			NewWritableProperty("globalIdentifier", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("userType", V2P(NewAccessUserType)),
+			NewOptionalProperty("userName", V2P(NewCharacterString)),
+			NewOptionalProperty("userExternalIdentifier", V2P(NewCharacterString)),
+			NewOptionalProperty("userInformationReference", V2P(NewCharacterString)),
+			NewOptionalProperty("members", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("memberOf", ListOfP(NewDeviceObjectReference)),
+			NewReadableProperty("credentials", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccessZoneObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccessZoneObject.go
new file mode 100644
index 0000000..b2c8cae
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccessZoneObject.go
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccessZoneObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccessZoneObject(arg Arg) (*AccessZoneObject, error) {
+	o := &AccessZoneObject{
+		objectType: "accessZone",
+		properties: []Property{
+			NewWritableProperty("globalIdentifier", V2P(NewUnsigned)),
+			NewReadableProperty("occupancyState", V2P(NewAccessZoneOccupancyState)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("occupancyCount", V2P(NewUnsigned)),
+			NewOptionalProperty("occupancyCountEnable", V2P(NewBoolean)),
+			NewOptionalProperty("adjustValue", V2P(NewInteger)),
+			NewOptionalProperty("occupancyUpperLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("occupancyLowerLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("credentialsInZone", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("lastCredentialAdded", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("lastCredentialAddedTime", V2P(NewDateTime)),
+			NewOptionalProperty("lastCredentialRemoved", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("lastCredentialRemovedTime", V2P(NewDateTime)),
+			NewOptionalProperty("passbackMode", V2P(NewAccessPassbackMode)),
+			NewOptionalProperty("passbackTimeout", V2P(NewUnsigned)),
+			NewReadableProperty("entryPoints", ListOfP(NewDeviceObjectReference)),
+			NewReadableProperty("exitPoints", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ListOfP(NewAccessZoneOccupancyState)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AccumulatorObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AccumulatorObject.go
new file mode 100644
index 0000000..db21bbf
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AccumulatorObject.go
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AccumulatorObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAccumulatorObject(arg Arg) (*AccumulatorObject, error) {
+	o := &AccumulatorObject{
+		objectType: "accumulator",
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewUnsigned)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("scale", V2P(NewScale)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("prescale", V2P(NewPrescale)),
+			NewReadableProperty("maxPresValue", V2P(NewUnsigned)),
+			NewOptionalProperty("valueChangeTime", V2P(NewDateTime)),
+			NewOptionalProperty("valueBeforeChange", V2P(NewUnsigned)),
+			NewOptionalProperty("valueSet", V2P(NewUnsigned)),
+			NewOptionalProperty("loggingRecord", V2P(NewAccumulatorRecord)),
+			NewOptionalProperty("loggingObject", Vs2P(NewObjectIdentifier)),
+			NewOptionalProperty("pulseRate", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("lowLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("limitMonitoringInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("faultHighLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("faultLowLimit", V2P(NewUnsigned)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AlertEnrollmentObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AlertEnrollmentObject.go
new file mode 100644
index 0000000..6f30f7f
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AlertEnrollmentObject.go
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AlertEnrollmentObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAlertEnrollmentObject(arg Arg) (*AlertEnrollmentObject, error) {
+	o := &AlertEnrollmentObject{
+		objectType: "alertEnrollment",
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewObjectIdentifier)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewReadableProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AnalogInputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogInputObject.go
new file mode 100644
index 0000000..9c5d376
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogInputObject.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AnalogInputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAnalogInputObject(arg Arg) (*AnalogInputObject, error) {
+	o := &AnalogInputObject{
+		objectType:           "analogInput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewReal)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("updateInterval", V2P(NewUnsigned)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("minPresValue", V2P(NewReal)),
+			NewOptionalProperty("maxPresValue", V2P(NewReal)),
+			NewOptionalProperty("resolution", V2P(NewReal)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewReal)),
+			NewOptionalProperty("lowLimit", V2P(NewReal)),
+			NewOptionalProperty("deadband", V2P(NewReal)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalReal)),
+			NewOptionalProperty("faultHighLimit", V2P(NewReal)),
+			NewOptionalProperty("faultLowLimit", V2P(NewReal)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AnalogOutputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogOutputObject.go
new file mode 100644
index 0000000..611b93e
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogOutputObject.go
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AnalogOutputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAnalogOutputObject(arg Arg) (*AnalogOutputObject, error) {
+	o := &AnalogOutputObject{
+		objectType:           "analogOutput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewReal)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("minPresValue", V2P(NewReal)),
+			NewOptionalProperty("maxPresValue", V2P(NewReal)),
+			NewOptionalProperty("resolution", V2P(NewReal)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewReadableProperty("relinquishDefault", V2P(NewReal)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewReal)),
+			NewOptionalProperty("lowLimit", V2P(NewReal)),
+			NewOptionalProperty("deadband", V2P(NewReal)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalReal)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AnalogValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogValueObject.go
new file mode 100644
index 0000000..4564d13
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AnalogValueObject.go
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AnalogValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAnalogValueObject(arg Arg) (*AnalogValueObject, error) {
+	o := &AnalogValueObject{
+		objectType:           "analogValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewReal)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("minPresValue", V2P(NewReal)),
+			NewOptionalProperty("maxPresValue", V2P(NewReal)),
+			NewOptionalProperty("resolution", V2P(NewReal)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewReal)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewReal)),
+			NewOptionalProperty("lowLimit", V2P(NewReal)),
+			NewOptionalProperty("deadband", V2P(NewReal)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("minPresValue", V2P(NewReal)),
+			NewOptionalProperty("maxPresValue", V2P(NewReal)),
+			NewOptionalProperty("resolution", V2P(NewReal)),
+			NewOptionalProperty("faultHighLimit", V2P(NewReal)),
+			NewOptionalProperty("faultLowLimit", V2P(NewReal)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AuditLogObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AuditLogObject.go
new file mode 100644
index 0000000..e3b3043
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AuditLogObject.go
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AuditLogObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAuditLogObject(arg Arg) (*AuditLogObject, error) {
+	o := &AuditLogObject{
+		objectType: "auditLog",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewWritableProperty("enable", V2P(NewBoolean)),
+			NewReadableProperty("bufferSize", V2P(NewUnsigned)), // Unsigned32
+			NewReadableProperty("logBuffer", ListOfP(NewAuditLogRecord)),
+			NewReadableProperty("recordCount", V2P(NewUnsigned)),      // Unsigned64
+			NewReadableProperty("totalRecordCount", V2P(NewUnsigned)), // Unsigned64
+			NewOptionalProperty("memberOf", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("deleteOnForward", V2P(NewBoolean)),
+			NewOptionalProperty("issueConfirmedNotifications", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AuditReporterObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AuditReporterObject.go
new file mode 100644
index 0000000..66c0cf5
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AuditReporterObject.go
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AuditReporterObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAuditReporterObject(arg Arg) (*AuditReporterObject, error) {
+	o := &AuditReporterObject{
+		objectType: "auditReporter",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("auditLevel", V2P(NewAuditLevel)),
+			NewReadableProperty("auditSourceReporter", V2P(NewBoolean)),
+			NewReadableProperty("auditableOperations", V2P(NewAuditOperationFlags)),
+			NewReadableProperty("auditablePriorityFilter", V2P(NewPriorityFilter)),
+			NewReadableProperty("issueConfirmedNotifications", V2P(NewBoolean)),
+			NewOptionalProperty("monitoredObjects", ArrayOfP(NewObjectSelector, 0, 0)),
+			NewOptionalProperty("maximumSendDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("sendNow", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_AveragingObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_AveragingObject.go
new file mode 100644
index 0000000..7b710fb
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_AveragingObject.go
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type AveragingObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewAveragingObject(arg Arg) (*AveragingObject, error) {
+	o := &AveragingObject{
+		objectType: "averaging",
+		properties: []Property{
+			NewReadableProperty("minimumValue", V2P(NewReal)),
+			NewOptionalProperty("minimumValueTimestamp", V2P(NewDateTime)),
+			NewReadableProperty("averageValue", V2P(NewReal)),
+			NewOptionalProperty("varianceValue", V2P(NewReal)),
+			NewReadableProperty("maximumValue", V2P(NewReal)),
+			NewOptionalProperty("maximumValueTimestamp", V2P(NewDateTime)),
+			NewWritableProperty("attemptedSamples", V2P(NewUnsigned)),
+			NewReadableProperty("validSamples", V2P(NewUnsigned)),
+			NewReadableProperty("objectPropertyReference", V2P(NewDeviceObjectPropertyReference)),
+			NewWritableProperty("windowInterval", V2P(NewUnsigned)),
+			NewWritableProperty("windowSamples", V2P(NewUnsigned)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_BinaryInputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryInputObject.go
new file mode 100644
index 0000000..3c69c79
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryInputObject.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type BinaryInputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewBinaryInputObject(arg Arg) (*BinaryInputObject, error) {
+	o := &BinaryInputObject{
+		objectType:           "binaryInput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewBinaryPV)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("polarity", V2P(NewPolarity)),
+			NewOptionalProperty("inactiveText", V2P(NewCharacterString)),
+			NewOptionalProperty("activeText", V2P(NewCharacterString)),
+			NewOptionalProperty("changeOfStateTime", V2P(NewDateTime)),
+			NewOptionalProperty("changeOfStateCount", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfStateCountReset", V2P(NewDateTime)),
+			NewOptionalProperty("elapsedActiveTime", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfActiveTimeReset", V2P(NewDateTime)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValue", V2P(NewBinaryPV)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalBinaryPV)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_BinaryLightingOutputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryLightingOutputObject.go
new file mode 100644
index 0000000..02154c9
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryLightingOutputObject.go
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type BinaryLightingOutputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewBinaryLightingOutputObject(arg Arg) (*BinaryLightingOutputObject, error) {
+	o := &BinaryLightingOutputObject{
+		objectType: "binaryLightingOutput",
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewBinaryLightingPV)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("blinkWarnEnable", V2P(NewBoolean)),
+			NewReadableProperty("egressTime", V2P(NewUnsigned)),
+			NewReadableProperty("egressActive", V2P(NewBoolean)),
+			NewOptionalProperty("feedbackValue", V2P(NewBinaryLightingPV)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewReadableProperty("relinquishDefault", V2P(NewBinaryLightingPV)),
+			NewOptionalProperty("power", V2P(NewReal)),
+			NewOptionalProperty("polarity", V2P(NewPolarity)),
+			NewOptionalProperty("elapsedActiveTime", V2P(NewUnsigned)), // Unsigned32,
+			NewOptionalProperty("timeOfActiveTimeReset", V2P(NewDateTime)),
+			NewOptionalProperty("strikeCount", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfStrikeCountReset", V2P(NewDateTime)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewReadableProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_BinaryOutputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryOutputObject.go
new file mode 100644
index 0000000..b086a63
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryOutputObject.go
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type BinaryOutputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewBinaryOutputObject(arg Arg) (*BinaryOutputObject, error) {
+	o := &BinaryOutputObject{
+		objectType:           "binaryOutput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewBinaryPV)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("polarity", V2P(NewPolarity)),
+			NewOptionalProperty("inactiveText", V2P(NewCharacterString)),
+			NewOptionalProperty("activeText", V2P(NewCharacterString)),
+			NewOptionalProperty("changeOfStateTime", V2P(NewDateTime)),
+			NewOptionalProperty("changeOfStateCount", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfStateCountReset", V2P(NewDateTime)),
+			NewOptionalProperty("elapsedActiveTime", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfActiveTimeReset", V2P(NewDateTime)),
+			NewOptionalProperty("minimumOffTime", V2P(NewUnsigned)),
+			NewOptionalProperty("minimumOnTime", V2P(NewUnsigned)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewReadableProperty("relinquishDefault", V2P(NewBinaryPV)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("feedbackValue", V2P(NewBinaryPV)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalBinaryPV)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_BinaryValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryValueObject.go
new file mode 100644
index 0000000..8ee93a1
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_BinaryValueObject.go
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type BinaryValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewBinaryValueObject(arg Arg) (*BinaryValueObject, error) {
+	o := &BinaryValueObject{
+		objectType:           "binaryValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewBinaryPV)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("inactiveText", V2P(NewCharacterString)),
+			NewOptionalProperty("activeText", V2P(NewCharacterString)),
+			NewOptionalProperty("changeOfStateTime", V2P(NewDateTime)),
+			NewOptionalProperty("changeOfStateCount", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfStateCountReset", V2P(NewDateTime)),
+			NewOptionalProperty("elapsedActiveTime", V2P(NewUnsigned)),
+			NewOptionalProperty("timeOfActiveTimeReset", V2P(NewDateTime)),
+			NewOptionalProperty("minimumOffTime", V2P(NewUnsigned)),
+			NewOptionalProperty("minimumOnTime", V2P(NewUnsigned)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewBinaryPV)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValue", V2P(NewBinaryPV)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_BitStringValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_BitStringValueObject.go
new file mode 100644
index 0000000..2135ee6
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_BitStringValueObject.go
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type BitStringValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewBitStringValueObject(arg Arg) (*BitStringValueObject, error) {
+	o := &BitStringValueObject{
+		objectType: "bitstringValue",
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewBitString)),
+			NewOptionalProperty("bitText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", Vs2P(NewBitString)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ArrayOfsP(NewBitString, 0, 0)),
+			NewOptionalProperty("bitMask", Vs2P(NewBitString)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_CalendarObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_CalendarObject.go
new file mode 100644
index 0000000..8afe2ad
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_CalendarObject.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type CalendarObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewCalendarObject(arg Arg) (*CalendarObject, error) {
+	o := &CalendarObject{
+		objectType: "calendar",
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewBoolean)),
+			NewReadableProperty("dateList", ListOfP(NewCalendarEntry)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ChannelObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_ChannelObject.go
new file mode 100644
index 0000000..a5a3c21
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ChannelObject.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type ChannelObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewChannelObject(arg Arg) (*ChannelObject, error) {
+	o := &ChannelObject{
+		objectType: "channel",
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewChannelValue)),
+			NewReadableProperty("lastPriority", V2P(NewUnsigned)),
+			NewReadableProperty("writeStatus", V2P(NewWriteStatus)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewWritableProperty("listOfObjectPropertyReferences", ArrayOfP(NewDeviceObjectPropertyReference, 0, 0)),
+			NewOptionalProperty("executionDelay", ArrayOfP(NewUnsigned, 0, 0)),
+			NewOptionalProperty("allowGroupDelayInhibit", V2P(NewBoolean)),
+			NewWritableProperty("channelNumber", V2P(NewUnsigned)),
+			NewWritableProperty("controlGroups", ArrayOfP(NewUnsigned, 0, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_CharacterStringValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_CharacterStringValueObject.go
new file mode 100644
index 0000000..3bba85c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_CharacterStringValueObject.go
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type CharacterStringValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewCharacterStringValueObject(arg Arg) (*CharacterStringValueObject, error) {
+	o := &CharacterStringValueObject{
+		objectType:           "characterstringValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewCharacterString)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ArrayOfP(NewOptionalCharacterString, 0, 0)),
+			NewOptionalProperty("faultValues", ArrayOfP(NewOptionalCharacterString, 0, 0)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_CommandObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_CommandObject.go
new file mode 100644
index 0000000..b24f108
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_CommandObject.go
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type CommandObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewCommandObject(arg Arg) (*CommandObject, error) {
+	o := &CommandObject{
+		objectType: "command",
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewUnsigned)),
+			NewReadableProperty("inProcess", V2P(NewBoolean)),
+			NewReadableProperty("allWritesSuccessful", V2P(NewBoolean)),
+			NewReadableProperty("action", ArrayOfP(NewActionList, 0, 0)),
+			NewOptionalProperty("actionText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_CredentialDataInputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_CredentialDataInputObject.go
new file mode 100644
index 0000000..3a7eabe
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_CredentialDataInputObject.go
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type CredentialDataInputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewCredentialDataInputObject(arg Arg) (*CredentialDataInputObject, error) {
+	o := &CredentialDataInputObject{
+		objectType:           "credentialDataInput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewAuthenticationFactor)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("supportedFormats", ArrayOfP(NewAuthenticationFactorFormat, 0, 0)),
+			NewOptionalProperty("supportedFormatClasses", ArrayOfP(NewUnsigned, 0, 0)),
+			NewReadableProperty("updateTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_DatePatternValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_DatePatternValueObject.go
new file mode 100644
index 0000000..0a2db47
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_DatePatternValueObject.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type DatePatternValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewDatePatternValueObject(arg Arg) (*DatePatternValueObject, error) {
+	o := &DatePatternValueObject{
+		objectType:           "datePatternValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewDate)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", Vs2P(NewDate)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_DateTimePatternValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_DateTimePatternValueObject.go
new file mode 100644
index 0000000..6add064
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_DateTimePatternValueObject.go
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type DateTimePatternValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewDateTimePatternValueObject(arg Arg) (*DateTimePatternValueObject, error) {
+	o := &DateTimePatternValueObject{
+		objectType:           "datetimePatternValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewDateTime)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("isUTC", V2P(NewBoolean)),
+
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewDateTime)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_DateTimeValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_DateTimeValueObject.go
new file mode 100644
index 0000000..b81ba2a
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_DateTimeValueObject.go
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type DateTimeValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewDateTimeValueObject(arg Arg) (*DateTimeValueObject, error) {
+	o := &DateTimeValueObject{
+		objectType:           "datetimeValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewDateTime)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewDateTime)),
+			NewOptionalProperty("isUTC", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_DateValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_DateValueObject.go
new file mode 100644
index 0000000..d8dc644
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_DateValueObject.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type DateValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewDateValueObject(arg Arg) (*DateValueObject, error) {
+	o := &DateValueObject{
+		objectType:           "dateValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewDate)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", Vs2P(NewDate)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_DeviceObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_DeviceObject.go
new file mode 100644
index 0000000..ae84ffe
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_DeviceObject.go
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type DeviceObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewDeviceObject(arg Arg) (*DeviceObject, error) {
+	o := &DeviceObject{
+		objectType: "device",
+		properties: []Property{
+			NewReadableProperty("systemStatus", V2P(NewDeviceStatus)),
+			NewReadableProperty("vendorName", V2P(NewCharacterString)),
+			NewReadableProperty("vendorIdentifier", V2P(NewUnsigned)),
+			NewReadableProperty("modelName", V2P(NewCharacterString)),
+			NewReadableProperty("firmwareRevision", V2P(NewCharacterString)),
+			NewReadableProperty("applicationSoftwareVersion", V2P(NewCharacterString)),
+			NewOptionalProperty("location", V2P(NewCharacterString)),
+			NewReadableProperty("protocolVersion", V2P(NewUnsigned)),
+			NewReadableProperty("protocolRevision", V2P(NewUnsigned)),
+			NewReadableProperty("protocolServicesSupported", V2P(NewServicesSupported)),
+			NewReadableProperty("protocolObjectTypesSupported", V2P(NewObjectTypesSupported)),
+			NewReadableProperty("objectList", ArrayOfsP(NewObjectIdentifier, 0, 0)),
+			NewOptionalProperty("structuredObjectList", ArrayOfsP(NewObjectIdentifier, 0, 0)),
+			NewReadableProperty("maxApduLengthAccepted", V2P(NewUnsigned)),
+			NewReadableProperty("segmentationSupported", V2P(NewSegmentation)),
+			NewOptionalProperty("vtClassesSupported", ListOfP(NewVTClass)),
+			NewOptionalProperty("activeVtSessions", ListOfP(NewVTSession)),
+			NewOptionalProperty("localTime", Vs2P(NewTime)),
+			NewOptionalProperty("localDate", Vs2P(NewDate)),
+			NewOptionalProperty("utcOffset", V2P(NewInteger)),
+			NewOptionalProperty("daylightSavingsStatus", V2P(NewBoolean)),
+			NewOptionalProperty("apduSegmentTimeout", V2P(NewUnsigned)),
+			NewReadableProperty("apduTimeout", V2P(NewUnsigned)),
+			NewReadableProperty("numberOfApduRetries", V2P(NewUnsigned)),
+			NewOptionalProperty("timeSynchronizationRecipients", ListOfP(NewRecipient)),
+			NewOptionalProperty("maxMaster", V2P(NewUnsigned)),
+			NewOptionalProperty("maxInfoFrames", V2P(NewUnsigned)),
+			NewReadableProperty("deviceAddressBinding", ListOfP(NewAddressBinding)),
+			NewReadableProperty("databaseRevision", V2P(NewUnsigned)),
+			NewOptionalProperty("configurationFiles", ArrayOfsP(NewObjectIdentifier, 0, 0)),
+			NewOptionalProperty("lastRestoreTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("backupFailureTimeout", V2P(NewUnsigned)),
+			NewOptionalProperty("backupPreparationTime", V2P(NewUnsigned)),
+			NewOptionalProperty("restorePreparationTime", V2P(NewUnsigned)),
+			NewOptionalProperty("restoreCompletionTime", V2P(NewUnsigned)),
+			NewOptionalProperty("backupAndRestoreState", V2P(NewBackupState)),
+			NewOptionalProperty("activeCovSubscriptions", ListOfP(NewCOVSubscription)),
+			NewOptionalProperty("maxSegmentsAccepted", V2P(NewUnsigned)),
+			NewOptionalProperty("slaveProxyEnable", ArrayOfP(NewBoolean, 0, 0)),
+			NewOptionalProperty("autoSlaveDiscovery", ArrayOfP(NewBoolean, 0, 0)),
+			NewOptionalProperty("slaveAddressBinding", ListOfP(NewAddressBinding)),
+			NewOptionalProperty("manualSlaveAddressBinding", ListOfP(NewAddressBinding)),
+			NewOptionalProperty("lastRestartReason", V2P(NewRestartReason)),
+			NewOptionalProperty("timeOfDeviceRestart", V2P(NewTimeStamp)),
+			NewOptionalProperty("restartNotificationRecipients", ListOfP(NewRecipient)),
+			NewOptionalProperty("utcTimeSynchronizationRecipients", ListOfP(NewRecipient)),
+			NewOptionalProperty("timeSynchronizationInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("alignIntervals", V2P(NewBoolean)),
+			NewOptionalProperty("intervalOffset", V2P(NewUnsigned)),
+			NewOptionalProperty("serialNumber", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("activeCovMultipleSubscriptions", ListOfP(NewCOVMultipleSubscription)),
+			NewOptionalProperty("auditNotificationRecipient", V2P(NewRecipient)),
+			NewOptionalProperty("deviceUUID", V2P(NewOctetString)), // size 16,
+			NewOptionalProperty("deployedProfileLocation", V2P(NewCharacterString)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ElevatorGroupObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_ElevatorGroupObject.go
new file mode 100644
index 0000000..7a4c85b
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ElevatorGroupObject.go
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type ElevatorGroupObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewElevatorGroupObject(arg Arg) (*ElevatorGroupObject, error) {
+	o := &ElevatorGroupObject{
+		objectType: "elevatorGroup",
+		properties: []Property{
+			NewReadableProperty("machineRoomID", Vs2P(NewObjectIdentifier)),
+			NewReadableProperty("groupID", V2P(NewUnsigned8)),
+			NewReadableProperty("groupMembers", ArrayOfsP(NewObjectIdentifier, 0, 0)),
+			NewOptionalProperty("groupMode", V2P(NewLiftGroupMode)),
+			NewOptionalProperty("landingCalls", ListOfP(NewLandingCallStatus)),
+			NewOptionalProperty("landingCallControl", V2P(NewLandingCallStatus)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_EscalatorObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_EscalatorObject.go
new file mode 100644
index 0000000..0368fc7
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_EscalatorObject.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type EscalatorObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewEscalatorObject(arg Arg) (*EscalatorObject, error) {
+	o := &EscalatorObject{
+		objectType: "escalator",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("elevatorGroup", Vs2P(NewObjectIdentifier)),
+			NewReadableProperty("groupID", V2P(NewUnsigned8)),
+			NewReadableProperty("installationID", V2P(NewUnsigned8)),
+			NewOptionalProperty("powerMode", V2P(NewBoolean)),
+			NewReadableProperty("operationDirection", V2P(NewEscalatorOperationDirection)),
+			NewOptionalProperty("escalatorMode", V2P(NewEscalatorMode)),
+			NewOptionalProperty("energyMeter", V2P(NewReal)),
+			NewOptionalProperty("energyMeterRef", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("faultSignals", ListOfP(NewLiftFault)),
+			NewReadableProperty("passengerAlarm", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_EventEnrollmentObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_EventEnrollmentObject.go
new file mode 100644
index 0000000..7b3d2fa
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_EventEnrollmentObject.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type EventEnrollmentObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewEventEnrollmentObject(arg Arg) (*EventEnrollmentObject, error) {
+	o := &EventEnrollmentObject{
+		objectType: "eventEnrollment",
+		properties: []Property{
+			NewReadableProperty("eventType", V2P(NewEventType)),
+			NewReadableProperty("notifyType", V2P(NewNotifyType)),
+			NewReadableProperty("eventParameters", V2P(NewEventParameter)),
+			NewReadableProperty("objectPropertyReference", V2P(NewDeviceObjectPropertyReference)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewReadableProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewReadableProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewReadableProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("faultType", V2P(NewFaultType)),
+			NewOptionalProperty("faultParameters", V2P(NewFaultParameter)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+
+	// TODO: @register_object_type
+	return o, nil
+}
+
+//-----
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_EventLogObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogObject.go
new file mode 100644
index 0000000..ceb2354
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogObject.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type EventLogObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewEventLogObject(arg Arg) (*EventLogObject, error) {
+	o := &EventLogObject{
+		objectType: "eventLog",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewWritableProperty("enable", V2P(NewBoolean)),
+			NewOptionalProperty("startTime", V2P(NewDateTime)),
+			NewOptionalProperty("stopTime", V2P(NewDateTime)),
+			NewReadableProperty("stopWhenFull", V2P(NewBoolean)),
+			NewReadableProperty("bufferSize", V2P(NewUnsigned)),
+			NewReadableProperty("logBuffer", ListOfP(NewEventLogRecord)),
+			NewWritableProperty("recordCount", V2P(NewUnsigned)),
+			NewReadableProperty("totalRecordCount", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationThreshold", V2P(NewUnsigned)),
+			NewOptionalProperty("recordsSinceNotification", V2P(NewUnsigned)),
+			NewOptionalProperty("lastNotifyRecord", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+
+		//-----
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecord.go b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecord.go
new file mode 100644
index 0000000..4e5cded
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecord.go
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/constructeddata"
+)
+
+type EventLogRecord struct {
+	*Sequence
+
+	sequenceElements []Element // TODO: migrate to super get call
+}
+
+func NewEventLogRecord(arg Arg) (*EventLogRecord, error) {
+	e := &EventLogRecord{
+		sequenceElements: []Element{
+			NewElement("timestamp", V2E(NewDateTime), WithElementContext(0)),
+			NewElement("logDatum", V2E(NewEventLogRecordLogDatum), WithElementContext(1)),
+		},
+	}
+	panic("implement me")
+	return e, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecordLogDatum.go b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecordLogDatum.go
new file mode 100644
index 0000000..535c825
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_EventLogRecordLogDatum.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/apdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/constructeddata"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type EventLogRecordLogDatum struct {
+	*Choice
+	choiceElements []Element
+}
+
+func NewEventLogRecordLogDatum(arg Arg) (*EventLogRecordLogDatum, error) {
+	e := &EventLogRecordLogDatum{
+		choiceElements: []Element{
+			NewElement("logStatus", V2E(NewLogStatus), WithElementContext(0)),
+			NewElement("notification", V2E(NewEventNotificationParameters), WithElementContext(1)),
+			NewElement("timeChange", V2E(NewReal), WithElementContext(2)),
+		},
+	}
+	panic("implemet me")
+	return e, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_FileObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_FileObject.go
new file mode 100644
index 0000000..6905fc3
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_FileObject.go
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type FileObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewFileObject(arg Arg) (*FileObject, error) {
+	o := &FileObject{
+		objectType: "file",
+		properties: []Property{
+			NewReadableProperty("fileType", V2P(NewCharacterString)),
+			NewReadableProperty("fileSize", V2P(NewUnsigned)),
+			NewReadableProperty("modificationDate", V2P(NewDateTime)),
+			NewWritableProperty("archive", V2P(NewBoolean)),
+			NewReadableProperty("readOnly", V2P(NewBoolean)),
+			NewReadableProperty("fileAccessMethod", V2P(NewFileAccessMethod)),
+			NewOptionalProperty("recordCount", V2P(NewUnsigned)),
+		},
+
+		//-----
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_GlobalGroupObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_GlobalGroupObject.go
new file mode 100644
index 0000000..253797d
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_GlobalGroupObject.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type GlobalGroupObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewGlobalGroupObject(arg Arg) (*GlobalGroupObject, error) {
+	o := &GlobalGroupObject{
+		objectType: "globalGroup",
+		properties: []Property{
+			NewReadableProperty("groupMembers", ArrayOfP(NewDeviceObjectPropertyReference, 0, 0)),
+			NewOptionalProperty("groupMemberNames", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("presentValue", ArrayOfP(NewPropertyAccessResult, 0, 0)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("memberStatusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("updateInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("requestedUpdateInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("covResubscriptionInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("clientCovIncrement", V2P(NewClientCOV)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("covuPeriod", V2P(NewUnsigned)),
+			NewOptionalProperty("covuRecipients", ListOfP(NewRecipient)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_GroupObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_GroupObject.go
new file mode 100644
index 0000000..b9ebdaa
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_GroupObject.go
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/apdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+)
+
+type GroupObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewGroupObject(arg Arg) (*GroupObject, error) {
+	o := &GroupObject{
+		objectType: "group",
+		properties: []Property{
+			NewReadableProperty("listOfGroupMembers", ListOfP(NewReadAccessSpecification)),
+			NewReadableProperty("presentValue", ListOfP(NewReadAccessResult)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_IntegerValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_IntegerValueObject.go
new file mode 100644
index 0000000..fe45b5e
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_IntegerValueObject.go
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type IntegerValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewIntegerValueObject(arg Arg) (*IntegerValueObject, error) {
+	o := &IntegerValueObject{
+		objectType:           "integerValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewInteger)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewInteger)),
+			NewOptionalProperty("covIncrement", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewInteger)),
+			NewOptionalProperty("lowLimit", V2P(NewInteger)),
+			NewOptionalProperty("deadband", V2P(NewUnsigned)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("minPresValue", V2P(NewInteger)),
+			NewOptionalProperty("maxPresValue", V2P(NewInteger)),
+			NewOptionalProperty("resolution", V2P(NewInteger)),
+			NewOptionalProperty("faultHighLimit", V2P(NewInteger)),
+			NewOptionalProperty("faultLowLimit", V2P(NewInteger)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LargeAnalogValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LargeAnalogValueObject.go
new file mode 100644
index 0000000..6935884
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LargeAnalogValueObject.go
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LargeAnalogValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLargeAnalogValueObject(arg Arg) (*LargeAnalogValueObject, error) {
+	o := &LargeAnalogValueObject{
+		objectType:           "largeAnalogValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewDouble)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewInteger)),
+			NewOptionalProperty("covIncrement", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewDouble)),
+			NewOptionalProperty("lowLimit", V2P(NewDouble)),
+			NewOptionalProperty("deadband", V2P(NewDouble)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("minPresValue", V2P(NewDouble)),
+			NewOptionalProperty("maxPresValue", V2P(NewDouble)),
+			NewOptionalProperty("resolution", V2P(NewDouble)),
+			NewOptionalProperty("faultHighLimit", V2P(NewDouble)),
+			NewOptionalProperty("faultLowLimit", V2P(NewDouble)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyPointObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyPointObject.go
new file mode 100644
index 0000000..5b5e784
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyPointObject.go
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LifeSafetyPointObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLifeSafetyPointObject(arg Arg) (*LifeSafetyPointObject, error) {
+	o := &LifeSafetyPointObject{
+		objectType:           "lifeSafetyPoint",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewLifeSafetyState)),
+			NewReadableProperty("trackingValue", V2P(NewLifeSafetyState)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewWritableProperty("mode", V2P(NewLifeSafetyMode)),
+			NewReadableProperty("acceptedModes", ListOfP(NewLifeSafetyMode)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("lifeSafetyAlarmValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("alarmValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("faultValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewReadableProperty("silenced", V2P(NewSilencedState)),
+			NewReadableProperty("operationExpected", V2P(NewLifeSafetyOperation)),
+			NewOptionalProperty("maintenanceRequired", V2P(NewMaintenance)),
+			NewOptionalProperty("setting", V2P(NewUnsigned)),
+			NewOptionalProperty("directReading", V2P(NewReal)),
+			NewOptionalProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("memberOf", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("floorNumber", V2P(NewUnsigned8)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyZoneObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyZoneObject.go
new file mode 100644
index 0000000..5d9bdb8
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LifeSafetyZoneObject.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LifeSafetyZoneObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLifeSafetyZoneObject(arg Arg) (*LifeSafetyZoneObject, error) {
+	o := &LifeSafetyZoneObject{
+		objectType:           "lifeSafetyZone",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewLifeSafetyState)),
+			NewReadableProperty("trackingValue", V2P(NewLifeSafetyState)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewWritableProperty("mode", V2P(NewLifeSafetyMode)),
+			NewReadableProperty("acceptedModes", ListOfP(NewLifeSafetyMode)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("lifeSafetyAlarmValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("alarmValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("faultValues", ListOfP(NewLifeSafetyState)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewReadableProperty("silenced", V2P(NewSilencedState)),
+			NewReadableProperty("operationExpected", V2P(NewLifeSafetyOperation)),
+			NewOptionalProperty("maintenanceRequired", V2P(NewBoolean)),
+			NewReadableProperty("zoneMembers", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("memberOf", ListOfP(NewDeviceObjectReference)),
+			NewOptionalProperty("floorNumber", V2P(NewUnsigned8)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LiftObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LiftObject.go
new file mode 100644
index 0000000..12f20ce
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LiftObject.go
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LiftObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLiftObject(arg Arg) (*LiftObject, error) {
+	o := &LiftObject{
+		objectType: "lift",
+		properties: []Property{
+			NewReadableProperty("trackingValue", V2P(NewReal)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("elevatorGroup", Vs2P(NewObjectIdentifier)),
+			NewReadableProperty("groupID", V2P(NewUnsigned8)),
+			NewReadableProperty("installationID", V2P(NewUnsigned8)),
+			NewOptionalProperty("floorText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("carDoorText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("assignedLandingCalls", ArrayOfP(NewAssignedLandingCalls, 0, 0)),
+			NewOptionalProperty("makingCarCall", ArrayOfP(NewUnsigned8, 0, 0)),
+			NewOptionalProperty("registeredCarCall", ArrayOfP(NewLiftCarCallList, 0, 0)),
+			NewOptionalProperty("carPosition", V2P(NewUnsigned8)),
+			NewOptionalProperty("carMovingDirection", V2P(NewLiftCarDirection)),
+			NewOptionalProperty("carAssignedDirection", V2P(NewLiftCarDirection)),
+			NewOptionalProperty("carDoorStatus", ArrayOfP(NewDoorStatus, 0, 0)),
+			NewOptionalProperty("carDoorCommand", ArrayOfP(NewLiftCarDoorCommand, 0, 0)),
+			NewOptionalProperty("carDoorZone", V2P(NewBoolean)),
+			NewOptionalProperty("carMode", V2P(NewLiftCarMode)),
+			NewOptionalProperty("carLoad", V2P(NewReal)),
+			NewOptionalProperty("carLoadUnits", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("nextStoppingFloor", V2P(NewUnsigned)),
+			NewReadableProperty("passengerAlarm", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("energyMeter", V2P(NewReal)),
+			NewOptionalProperty("energyMeterRef", V2P(NewDeviceObjectReference)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("carDriveStatus", V2P(NewLiftCarDriveStatus)),
+			NewOptionalProperty("faultSignals", ListOfP(NewLiftFault)),
+			NewOptionalProperty("landingDoorStatus", ArrayOfP(NewLandingDoorStatus, 0, 0)),
+			NewOptionalProperty("higherDeck", Vs2P(NewObjectIdentifier)),
+			NewOptionalProperty("lowerDeck", Vs2P(NewObjectIdentifier)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LightingOutputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LightingOutputObject.go
new file mode 100644
index 0000000..245d3f7
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LightingOutputObject.go
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LightingOutputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLightingOutputObject(arg Arg) (*LightingOutputObject, error) {
+	o := &LightingOutputObject{
+		objectType:           "lightingOutput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewReal)),
+			NewReadableProperty("trackingValue", V2P(NewReal)),
+			NewWritableProperty("lightingCommand", V2P(NewLightingCommand)),
+			NewReadableProperty("inProgress", V2P(NewLightingInProgress)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("blinkWarnEnable", V2P(NewBoolean)),
+			NewReadableProperty("egressTime", V2P(NewUnsigned)),
+			NewReadableProperty("egressActive", V2P(NewBoolean)),
+			NewReadableProperty("defaultFadeTime", V2P(NewUnsigned)),
+			NewReadableProperty("defaultRampRate", V2P(NewReal)),
+			NewReadableProperty("defaultStepIncrement", V2P(NewReal)),
+			NewOptionalProperty("transition", V2P(NewLightingTransition)),
+			NewOptionalProperty("feedbackValue", V2P(NewReal)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewReadableProperty("relinquishDefault", V2P(NewReal)),
+			NewOptionalProperty("power", V2P(NewReal)),
+			NewOptionalProperty("instantaneousPower", V2P(NewReal)),
+			NewOptionalProperty("minActualValue", V2P(NewReal)),
+			NewOptionalProperty("maxActualValue", V2P(NewReal)),
+			NewReadableProperty("lightingCommandDefaultPriority", V2P(NewUnsigned)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LoadControlObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LoadControlObject.go
new file mode 100644
index 0000000..4a0d06b
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LoadControlObject.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LoadControlObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLoadControlObject(arg Arg) (*LoadControlObject, error) {
+	o := &LoadControlObject{
+		objectType:           "loadControl",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewShedState)),
+			NewOptionalProperty("stateDescription", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewWritableProperty("requestedShedLevel", V2P(NewShedLevel)),
+			NewWritableProperty("startTime", V2P(NewDateTime)),
+			NewWritableProperty("shedDuration", V2P(NewUnsigned)),
+			NewWritableProperty("dutyWindow", V2P(NewUnsigned)),
+			NewWritableProperty("enable", V2P(NewBoolean)),
+			NewOptionalProperty("fullDutyBaseline", V2P(NewReal)),
+			NewReadableProperty("expectedShedLevel", V2P(NewShedLevel)),
+			NewReadableProperty("actualShedLevel", V2P(NewShedLevel)),
+			NewWritableProperty("shedLevels", ArrayOfP(NewUnsigned, 0, 0)),
+			NewReadableProperty("shedLevelDescriptions", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_LoopObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_LoopObject.go
new file mode 100644
index 0000000..4be90db
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_LoopObject.go
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type LoopObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewLoopObject(arg Arg) (*LoopObject, error) {
+	o := &LoopObject{
+		objectType:           "loop",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewReal)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("updateInterval", V2P(NewUnsigned)),
+			NewReadableProperty("outputUnits", V2P(NewEngineeringUnits)),
+			NewReadableProperty("manipulatedVariableReference", V2P(NewObjectPropertyReference)),
+			NewReadableProperty("controlledVariableReference", V2P(NewObjectPropertyReference)),
+			NewReadableProperty("controlledVariableValue", V2P(NewReal)),
+			NewReadableProperty("controlledVariableUnits", V2P(NewEngineeringUnits)),
+			NewReadableProperty("setpointReference", V2P(NewSetpointReference)),
+			NewReadableProperty("setpoint", V2P(NewReal)),
+			NewReadableProperty("action", V2P(NewAction)),
+			NewOptionalProperty("proportionalConstant", V2P(NewReal)),
+			NewOptionalProperty("proportionalConstantUnits", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("integralConstant", V2P(NewReal)),
+			NewOptionalProperty("integralConstantUnits", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("derivativeConstant", V2P(NewReal)),
+			NewOptionalProperty("derivativeConstantUnits", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("bias", V2P(NewReal)),
+			NewOptionalProperty("maximumOutput", V2P(NewReal)),
+			NewOptionalProperty("minimumOutput", V2P(NewReal)),
+			NewReadableProperty("priorityForWriting", V2P(NewUnsigned)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("errorLimit", V2P(NewReal)),
+			NewOptionalProperty("deadband", V2P(NewReal)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("lowDiffLimit", V2P(NewOptionalReal)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateInputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateInputObject.go
new file mode 100644
index 0000000..24e611c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateInputObject.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type MultiStateInputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewMultiStateInputObject(arg Arg) (*MultiStateInputObject, error) {
+	o := &MultiStateInputObject{
+		objectType:           "multiStateInput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewUnsigned)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("numberOfStates", V2P(NewUnsigned)),
+			NewOptionalProperty("stateText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ListOfP(NewUnsigned)),
+			NewOptionalProperty("faultValues", ListOfP(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalUnsigned)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateOutputObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateOutputObject.go
new file mode 100644
index 0000000..b7fe894
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateOutputObject.go
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type MultiStateOutputObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewMultiStateOutputObject(arg Arg) (*MultiStateOutputObject, error) {
+	o := &MultiStateOutputObject{
+		objectType:           "multiStateOutput",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewUnsigned)),
+			NewOptionalProperty("deviceType", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("numberOfStates", V2P(NewUnsigned)),
+			NewOptionalProperty("stateText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("feedbackValue", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("interfaceValue", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateValueObject.go
new file mode 100644
index 0000000..796602a
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_MultiStateValueObject.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type MultiStateValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewMultiStateValueObject(arg Arg) (*MultiStateValueObject, error) {
+	o := &MultiStateValueObject{
+		objectType:           "multiStateValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("numberOfStates", V2P(NewUnsigned)),
+			NewOptionalProperty("stateText", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ListOfP(NewUnsigned)),
+			NewOptionalProperty("faultValues", ListOfP(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_NetworkPortObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_NetworkPortObject.go
new file mode 100644
index 0000000..448af6c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_NetworkPortObject.go
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type NetworkPortObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewNetworkPortObject(arg Arg) (*NetworkPortObject, error) {
+	o := &NetworkPortObject{
+		objectType: "networkPort", //56,
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),                      //111
+			NewReadableProperty("reliability", V2P(NewReliability)),                      //103
+			NewReadableProperty("outOfService", V2P(NewBoolean)),                         //81
+			NewReadableProperty("networkType", V2P(NewNetworkType)),                      //427
+			NewReadableProperty("protocolLevel", V2P(NewProtocolLevel)),                  //482
+			NewOptionalProperty("referencePort", V2P(NewUnsigned)),                       //483
+			NewReadableProperty("networkNumber", V2P(NewUnsigned16)),                     //425
+			NewReadableProperty("networkNumberQuality", V2P(NewNetworkNumberQuality)),    //426
+			NewReadableProperty("changesPending", V2P(NewBoolean)),                       //416
+			NewOptionalProperty("command", V2P(NewNetworkPortCommand)),                   //417
+			NewOptionalProperty("macAddress", V2P(NewOctetString)),                       //423
+			NewReadableProperty("apduLength", V2P(NewUnsigned)),                          //399
+			NewReadableProperty("linkSpeed", V2P(NewReal)),                               //420
+			NewOptionalProperty("linkSpeeds", ArrayOfP(NewReal, 0, 0)),                   //421
+			NewOptionalProperty("linkSpeedAutonegotiate", V2P(NewBoolean)),               //422
+			NewOptionalProperty("networkInterfaceName", V2P(NewCharacterString)),         //424
+			NewOptionalProperty("bacnetIPMode", V2P(NewIPMode)),                          //408
+			NewOptionalProperty("ipAddress", V2P(NewOctetString)),                        //400
+			NewOptionalProperty("bacnetIPUDPPort", V2P(NewUnsigned16)),                   //412
+			NewOptionalProperty("ipSubnetMask", V2P(NewOctetString)),                     //411
+			NewOptionalProperty("ipDefaultGateway", V2P(NewOctetString)),                 //401
+			NewOptionalProperty("bacnetIPMulticastAddress", V2P(NewOctetString)),         //409
+			NewOptionalProperty("ipDNSServer", ArrayOfP(NewOctetString, 0, 0)),           //406
+			NewOptionalProperty("ipDHCPEnable", V2P(NewBoolean)),                         //402
+			NewOptionalProperty("ipDHCPLeaseTime", V2P(NewUnsigned)),                     //403
+			NewOptionalProperty("ipDHCPLeaseTimeRemaining", V2P(NewUnsigned)),            //404
+			NewOptionalProperty("ipDHCPServer", V2P(NewOctetString)),                     //405
+			NewOptionalProperty("bacnetIPNATTraversal", V2P(NewBoolean)),                 //410
+			NewOptionalProperty("bacnetIPGlobalAddress", V2P(NewHostNPort)),              //407
+			NewOptionalProperty("bbmdBroadcastDistributionTable", ListOfP(NewBDTEntry)),  //414
+			NewOptionalProperty("bbmdAcceptFDRegistrations", V2P(NewBoolean)),            //413
+			NewOptionalProperty("bbmdForeignDeviceTable", ListOfP(NewFDTEntry)),          //415
+			NewOptionalProperty("fdBBMDAddress", V2P(NewHostNPort)),                      //418
+			NewOptionalProperty("fdSubscriptionLifetime", V2P(NewUnsigned16)),            //419
+			NewOptionalProperty("bacnetIPv6Mode", V2P(NewIPMode)),                        //435
+			NewOptionalProperty("ipv6Address", V2P(NewOctetString)),                      //436
+			NewOptionalProperty("ipv6PrefixLength", V2P(NewUnsigned8)),                   //437
+			NewOptionalProperty("bacnetIPv6UDPPort", V2P(NewUnsigned16)),                 //438
+			NewOptionalProperty("ipv6DefaultGateway", V2P(NewOctetString)),               //439
+			NewOptionalProperty("bacnetIPv6MulticastAddress", V2P(NewOctetString)),       //440
+			NewOptionalProperty("ipv6DNSServer", V2P(NewOctetString)),                    //441
+			NewOptionalProperty("ipv6AutoAddressingEnable", V2P(NewBoolean)),             //442
+			NewOptionalProperty("ipv6DHCPLeaseTime", V2P(NewUnsigned)),                   //443
+			NewOptionalProperty("ipv6DHCPLeaseTimeRemaining", V2P(NewUnsigned)),          //444
+			NewOptionalProperty("ipv6DHCPServer", V2P(NewOctetString)),                   //445
+			NewOptionalProperty("ipv6ZoneIndex", V2P(NewCharacterString)),                //446
+			NewOptionalProperty("maxMaster", V2P(NewUnsigned8)),                          //64
+			NewOptionalProperty("maxInfoFrames", V2P(NewUnsigned8)),                      //63
+			NewOptionalProperty("slaveProxyEnable", V2P(NewBoolean)),                     //172
+			NewOptionalProperty("manualSlaveAddressBinding", ListOfP(NewAddressBinding)), //170
+			NewOptionalProperty("autoSlaveDiscovery", V2P(NewBoolean)),                   //169
+			NewOptionalProperty("slaveAddressBinding", ListOfP(NewAddressBinding)),       //171
+			NewOptionalProperty("virtualMACAddressTable", ListOfP(NewVMACEntry)),         //429
+			NewOptionalProperty("routingTable", ListOfP(NewRouterEntry)),                 //428
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),                 //353
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),                   //17
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),              //35
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),         //0
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),                        //72
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),                //36,
+			NewReadableProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)), //357,
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_NetworkSecurityObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_NetworkSecurityObject.go
new file mode 100644
index 0000000..4b2922f
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_NetworkSecurityObject.go
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type NetworkSecurityObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewNetworkSecurityObject(arg Arg) (*NetworkSecurityObject, error) {
+	o := &NetworkSecurityObject{
+		objectType: "networkSecurity",
+		properties: []Property{
+			NewWritableProperty("baseDeviceSecurityPolicy", V2P(NewSecurityLevel)),
+			NewWritableProperty("networkAccessSecurityPolicies", ArrayOfP(NewNetworkSecurityPolicy, 0, 0)),
+			NewWritableProperty("securityTimeWindow", V2P(NewUnsigned)),
+			NewWritableProperty("packetReorderTime", V2P(NewUnsigned)),
+			NewReadableProperty("distributionKeyRevision", V2P(NewUnsigned)),
+			NewReadableProperty("keySets", ArrayOfP(NewSecurityKeySet, 0, 0)),
+			NewWritableProperty("lastKeyServer", V2P(NewAddressBinding)),
+			NewWritableProperty("securityPDUTimeout", V2P(NewUnsigned)),
+			NewReadableProperty("updateKeySetTimeout", V2P(NewUnsigned)),
+			NewReadableProperty("supportedSecurityAlgorithms", ListOfP(NewUnsigned)),
+			NewWritableProperty("doNotHide", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_NotificationClassObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_NotificationClassObject.go
new file mode 100644
index 0000000..3b579d0
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_NotificationClassObject.go
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type NotificationClassObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewNotificationClassObject(arg Arg) (*NotificationClassObject, error) {
+	o := &NotificationClassObject{
+		objectType: "notificationClass",
+		properties: []Property{
+			NewReadableProperty("notificationClass", V2P(NewUnsigned)),
+			NewReadableProperty("priority", ArrayOfP(NewUnsigned, 0, 0)),
+			NewReadableProperty("ackRequired", V2P(NewEventTransitionBits)),
+			NewReadableProperty("recipientList", ListOfP(NewDestination)),
+			NewOptionalProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewReadableProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_NotificationForwarderObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_NotificationForwarderObject.go
new file mode 100644
index 0000000..e963f6e
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_NotificationForwarderObject.go
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type NotificationForwarderObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewNotificationForwarderObject(arg Arg) (*NotificationForwarderObject, error) {
+	o := &NotificationForwarderObject{
+		objectType: "notificationForwarder",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("recipientList", ListOfP(NewDestination)),
+			NewWritableProperty("subscribedRecipients", ListOfP(NewEventNotificationSubscription)),
+			NewReadableProperty("processIdentifierFilter", V2P(NewProcessIdSelection)),
+			NewOptionalProperty("portFilter", ArrayOfP(NewPortPermission, 0, 0)),
+			NewReadableProperty("localForwardingOnly", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_Object.go b/plc4go/internal/bacnetip/bacgopes/object/object_Object.go
new file mode 100644
index 0000000..3b35680
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_Object.go
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+// TODO: big WIP
+type Object interface {
+}
+
+type _Object struct {
+	// TODO: debug contents
+	_objectSupportsCov bool
+
+	properties []Property
+}
+
+func NewObject() (Object, error) {
+	o := &_Object{
+		properties: []Property{
+			NewObjectIdentifierProperty("objectIdentifier", Vs2P(NewObjectIdentifier), WithPropertyOptional(false)),
+			NewReadableProperty("objectName", V2P(NewCharacterString), WithPropertyOptional(false)),
+			NewOptionalProperty("description", V2P(NewCharacterString)),
+			NewOptionalProperty("profileName", V2P(NewCharacterString)),
+			NewReadableProperty("propertyList", ArrayOfP(NewPropertyIdentifier, 0, 0)),
+			NewOptionalProperty("auditLevel", V2P(NewAuditLevel)),
+			NewOptionalProperty("auditableOperations", V2P(NewAuditOperationFlags)),
+			NewOptionalProperty("tags", ArrayOfsP(NewNameValue, 0, 0)),
+			NewOptionalProperty("profileLocation", V2P(NewCharacterString)),
+			NewOptionalProperty("profileName", V2P(NewCharacterString)),
+		},
+	}
+	panic("implement me")
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/object/object_ObjectIdentifierProperty.go
similarity index 75%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/object/object_ObjectIdentifierProperty.go
index efbea52..b12076b 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ObjectIdentifierProperty.go
@@ -21,15 +21,11 @@
 
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
+// TODO: big WIP
+type ObjectIdentifierProperty interface {
+	ReadableProperty
 }
 
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
+func NewObjectIdentifierProperty(name string, klass func(Args, KWArgs) (PropertyKlass, error), opts ...func(property *_Property)) ObjectIdentifierProperty {
 	panic("implement me")
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_OctetStringValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_OctetStringValueObject.go
new file mode 100644
index 0000000..cb079a8
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_OctetStringValueObject.go
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type OctetStringValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewOctetStringValueObject(arg Arg) (*OctetStringValueObject, error) {
+	o := &OctetStringValueObject{
+		objectType:           "octetstringValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewOctetString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewOctetString)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/object/object_OptionalProperty.go
similarity index 75%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/object/object_OptionalProperty.go
index efbea52..d1c29cf 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_OptionalProperty.go
@@ -21,15 +21,11 @@
 
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
+// TODO: big WIP
+type OptionalProperty interface {
+	StandardProperty
 }
 
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
+func NewOptionalProperty(name string, klass func(Args, KWArgs) (PropertyKlass, error), opts ...func(*PropertyKlass)) OptionalProperty {
 	panic("implement me")
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_PositiveIntegerValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_PositiveIntegerValueObject.go
new file mode 100644
index 0000000..ff1e19e
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_PositiveIntegerValueObject.go
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type PositiveIntegerValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewPositiveIntegerValueObject(arg Arg) (*PositiveIntegerValueObject, error) {
+	o := &PositiveIntegerValueObject{
+		objectType:           "positiveIntegerValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", V2P(NewUnsigned)),
+			NewOptionalProperty("covIncrement", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("lowLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("deadband", V2P(NewUnsigned)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("minPresValue", V2P(NewUnsigned)),
+			NewOptionalProperty("maxPresValue", V2P(NewUnsigned)),
+			NewOptionalProperty("resolution", V2P(NewUnsigned)),
+			NewOptionalProperty("faultHighLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("faultLowLimit", V2P(NewUnsigned)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ProgramObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_ProgramObject.go
new file mode 100644
index 0000000..88d531c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ProgramObject.go
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type ProgramObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewProgramObject(arg Arg) (*ProgramObject, error) {
+	o := &ProgramObject{
+		objectType: "program",
+		properties: []Property{
+			NewReadableProperty("programState", V2P(NewProgramState)),
+			NewWritableProperty("programChange", V2P(NewProgramRequest)),
+			NewOptionalProperty("reasonForHalt", V2P(NewProgramError)),
+			NewOptionalProperty("descriptionOfHalt", V2P(NewCharacterString)),
+			NewOptionalProperty("programLocation", V2P(NewCharacterString)),
+			NewOptionalProperty("instanceOf", V2P(NewCharacterString)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_Property.go b/plc4go/internal/bacnetip/bacgopes/object/object_Property.go
index 64cf784..a224285 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_Property.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_Property.go
@@ -19,6 +19,42 @@
 
 package object
 
-type Property struct {
-	//TODO: implement me
+import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+
+// TODO: big WIP
+type Property interface {
+	ReadProperty()
+	WriteProperty()
+}
+
+type PropertyKlass interface {
+	Encode(Arg) error
+}
+
+func NewProperty(name string, klass func(Args, KWArgs) (PropertyKlass, error), opts ...func(*PropertyKlass)) Property {
+	return &_Property{}
+}
+
+type _Property struct {
+	Name     string
+	Klass    func(Args, KWArgs) (PropertyKlass, error)
+	Optional bool
+}
+
+var _ Property = (*_Property)(nil)
+
+func WithPropertyOptional(optional bool) func(*_Property) {
+	return func(e *_Property) {
+		e.Optional = optional
+	}
+}
+
+func (p *_Property) ReadProperty() {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (p *_Property) WriteProperty() {
+	//TODO implement me
+	panic("implement me")
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_PulseConverterObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_PulseConverterObject.go
new file mode 100644
index 0000000..58ede00
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_PulseConverterObject.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type PulseConverterObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewPulseConverterObject(arg Arg) (*PulseConverterObject, error) {
+	o := &PulseConverterObject{
+		objectType:           "pulseConverter",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewReal)),
+			NewOptionalProperty("inputReference", V2P(NewObjectPropertyReference)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewReadableProperty("scaleFactor", V2P(NewReal)),
+			NewWritableProperty("adjustValue", V2P(NewReal)),
+			NewReadableProperty("count", V2P(NewUnsigned)),
+			NewReadableProperty("updateTime", V2P(NewDateTime)),
+			NewReadableProperty("countChangeTime", V2P(NewDateTime)),
+			NewReadableProperty("countBeforeChange", V2P(NewUnsigned)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("covPeriod", V2P(NewUnsigned)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("highLimit", V2P(NewReal)),
+			NewOptionalProperty("lowLimit", V2P(NewReal)),
+			NewOptionalProperty("deadband", V2P(NewReal)),
+			NewOptionalProperty("limitEnable", V2P(NewLimitEnable)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/object/object_ReadableProperty.go
similarity index 75%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/object/object_ReadableProperty.go
index efbea52..a11f8aa 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ReadableProperty.go
@@ -21,15 +21,12 @@
 
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
-}
-
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
+// TODO: big WIP
+type ReadableProperty interface {
+	StandardProperty
 	// TODO: implement me
-	return nil, nil
 }
 
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+func NewReadableProperty(name string, klass func(Args, KWArgs) (PropertyKlass, error), opts ...func(property *_Property)) ReadableProperty {
+	panic("impllement me") // TODO: implement me
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ScheduleObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_ScheduleObject.go
new file mode 100644
index 0000000..be62f32
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_ScheduleObject.go
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/constructeddata"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type ScheduleObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewScheduleObject(arg Arg) (*ScheduleObject, error) {
+	o := &ScheduleObject{
+		objectType: "schedule",
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewAnyAtomic)),
+			NewReadableProperty("effectivePeriod", V2P(NewDateRange)),
+			NewOptionalProperty("weeklySchedule", ArrayOfP(NewDailySchedule, 7, 0)),
+			NewOptionalProperty("exceptionSchedule", ArrayOfP(NewSpecialEvent, 0, 0)),
+			NewReadableProperty("scheduleDefault", Vs2P(NewAnyAtomic)),
+			NewReadableProperty("listOfObjectPropertyReferences", ListOfP(NewDeviceObjectPropertyReference)),
+			NewReadableProperty("priorityForWriting", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_StagingObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_StagingObject.go
new file mode 100644
index 0000000..685dede
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_StagingObject.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type StagingObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewStagingObject(arg Arg) (*StagingObject, error) {
+	o := &StagingObject{
+		objectType: "staging",
+		properties: []Property{
+			NewWritableProperty("presentValue", V2P(NewReal)),
+			NewReadableProperty("presentStage", V2P(NewUnsigned)),
+			NewReadableProperty("stages", ArrayOfP(NewStageLimitValue, 0, 0)),
+			NewOptionalProperty("stageNames", ArrayOfP(NewCharacterString, 0, 0)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewReadableProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("units", V2P(NewEngineeringUnits)),
+			NewReadableProperty("targetReferences", ArrayOfP(NewDeviceObjectReference, 0, 0)),
+			NewReadableProperty("priorityForWriting", V2P(NewUnsigned)), // 1..16
+			NewOptionalProperty("defaultPresentValue", V2P(NewReal)),
+			NewReadableProperty("minPresValue", V2P(NewReal)),
+			NewReadableProperty("maxPresValue", V2P(NewReal)),
+			NewOptionalProperty("covIncrement", V2P(NewReal)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/object/object_StandardProperty.go
similarity index 68%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/object/object_StandardProperty.go
index efbea52..c8599df 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_StandardProperty.go
@@ -19,17 +19,8 @@
 
 package object
 
-import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
-
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
-}
-
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
+// TODO: big WIP
+type StandardProperty interface {
+	Property
 	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_StructuredViewObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_StructuredViewObject.go
new file mode 100644
index 0000000..830b6a5
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_StructuredViewObject.go
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type StructuredViewObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewStructuredViewObject(arg Arg) (*StructuredViewObject, error) {
+	o := &StructuredViewObject{
+		objectType: "structuredView",
+		properties: []Property{
+			NewReadableProperty("nodeType", V2P(NewNodeType)),
+			NewOptionalProperty("nodeSubtype", V2P(NewCharacterString)),
+			NewReadableProperty("subordinateList", ArrayOfP(NewDeviceObjectReference, 0, 0)),
+			NewOptionalProperty("subordinateAnnotations", ArrayOfP(NewCharacterString, 0, 0)),
+			NewOptionalProperty("subordinateTags", ArrayOfP(NewNameValueCollection, 0, 0)),
+			NewOptionalProperty("subordinateNodeTypes", ArrayOfP(NewNodeType, 0, 0)),
+			NewOptionalProperty("subordinateRelationships", ArrayOfP(NewRelationship, 0, 0)),
+			NewOptionalProperty("defaultSubordinateRelationship", V2P(NewRelationship)),
+			NewOptionalProperty("represents", V2P(NewDeviceObjectReference)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_TimePatternValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_TimePatternValueObject.go
new file mode 100644
index 0000000..3fc3ab8
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_TimePatternValueObject.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type TimePatternValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewTimePatternValueObject(arg Arg) (*TimePatternValueObject, error) {
+	o := &TimePatternValueObject{
+		objectType:           "timePatternValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewTime)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", Vs2P(NewTime)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_TimeValueObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_TimeValueObject.go
new file mode 100644
index 0000000..e48c3a0
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_TimeValueObject.go
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type TimeValueObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewTimeValueObject(arg Arg) (*TimeValueObject, error) {
+	o := &TimeValueObject{
+		objectType:           "timeValue",
+		_object_supports_cov: true,
+		properties: []Property{
+			NewReadableProperty("presentValue", Vs2P(NewTime)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewOptionalProperty("priorityArray", V2P(NewPriorityArray)),
+			NewOptionalProperty("relinquishDefault", Vs2P(NewTime)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("currentCommandPriority", V2P(NewOptionalUnsigned)),
+			NewOptionalProperty("valueSource", V2P(NewValueSource)),
+			NewOptionalProperty("valueSourceArray", ArrayOfP(NewValueSource, 16, 0)),
+			NewOptionalProperty("lastCommandTime", V2P(NewTimeStamp)),
+			NewOptionalProperty("commandTimeArray", ArrayOfP(NewTimeStamp, 16, 0)),
+			NewOptionalProperty("auditablePriorityFilter", V2P(NewOptionalPriorityFilter)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_TimerObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_TimerObject.go
new file mode 100644
index 0000000..7622566
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_TimerObject.go
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type TimerObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewTimerObject(arg Arg) (*TimerObject, error) {
+	o := &TimerObject{
+		objectType: "timer",
+		properties: []Property{
+			NewReadableProperty("presentValue", V2P(NewUnsigned)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("outOfService", V2P(NewBoolean)),
+			NewReadableProperty("timerState", V2P(NewTimerState)),
+			NewReadableProperty("timerRunning", V2P(NewBoolean)),
+			NewOptionalProperty("updateTime", V2P(NewDateTime)),
+			NewOptionalProperty("lastStateChange", V2P(NewTimerTransition)),
+			NewOptionalProperty("expirationTime", V2P(NewDateTime)),
+			NewOptionalProperty("initialTimeout", V2P(NewUnsigned)),
+			NewOptionalProperty("defaultTimeout", V2P(NewUnsigned)),
+			NewOptionalProperty("minPresValue", V2P(NewUnsigned)),
+			NewOptionalProperty("maxPresValue", V2P(NewUnsigned)),
+			NewOptionalProperty("resolution", V2P(NewUnsigned)),
+			NewOptionalProperty("stateChangeValues", ArrayOfP(NewTimerStateChangeValue, 7, 0)),
+			NewOptionalProperty("listOfObjectPropertyReferences", ListOfP(NewDeviceObjectPropertyReference)),
+			NewOptionalProperty("priorityForWriting", V2P(NewUnsigned)), // 1..16
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelay", V2P(NewUnsigned)),
+			NewOptionalProperty("timeDelayNormal", V2P(NewUnsigned)),
+			NewOptionalProperty("alarmValues", ListOfP(NewTimerState)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_TrendLogObject.go b/plc4go/internal/bacnetip/bacgopes/object/object_TrendLogObject.go
new file mode 100644
index 0000000..df32062
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_TrendLogObject.go
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package object
+
+import (
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/basetypes"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/primitivedata"
+)
+
+type TrendLogObject struct {
+	Object
+	objectType           string // TODO: migrateme
+	properties           []Property
+	_object_supports_cov bool
+}
+
+func NewTrendLogObject(arg Arg) (*TrendLogObject, error) {
+	o := &TrendLogObject{
+		objectType: "trendLog",
+		properties: []Property{
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewWritableProperty("enable", V2P(NewBoolean)),
+			NewOptionalProperty("startTime", V2P(NewDateTime)),
+			NewOptionalProperty("stopTime", V2P(NewDateTime)),
+			NewOptionalProperty("logDeviceObjectProperty", V2P(NewDeviceObjectPropertyReference)),
+			NewOptionalProperty("logInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("covResubscriptionInterval", V2P(NewUnsigned)),
+			NewOptionalProperty("clientCovIncrement", V2P(NewClientCOV)),
+			NewReadableProperty("stopWhenFull", V2P(NewBoolean)),
+			NewReadableProperty("bufferSize", V2P(NewUnsigned)),
+			NewReadableProperty("logBuffer", ListOfP(NewLogRecord)),
+			NewWritableProperty("recordCount", V2P(NewUnsigned)),
+			NewReadableProperty("totalRecordCount", V2P(NewUnsigned)),
+			NewReadableProperty("loggingType", V2P(NewLoggingType)),
+			NewOptionalProperty("alignIntervals", V2P(NewBoolean)),
+			NewOptionalProperty("intervalOffset", V2P(NewUnsigned)),
+			NewOptionalProperty("trigger", V2P(NewBoolean)),
+			NewReadableProperty("statusFlags", V2P(NewStatusFlags)),
+			NewOptionalProperty("reliability", V2P(NewReliability)),
+			NewOptionalProperty("notificationThreshold", V2P(NewUnsigned)),
+			NewOptionalProperty("recordsSinceNotification", V2P(NewUnsigned)),
+			NewOptionalProperty("lastNotifyRecord", V2P(NewUnsigned)),
+			NewReadableProperty("eventState", V2P(NewEventState)),
+			NewOptionalProperty("notificationClass", V2P(NewUnsigned)),
+			NewOptionalProperty("eventEnable", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("ackedTransitions", V2P(NewEventTransitionBits)),
+			NewOptionalProperty("notifyType", V2P(NewNotifyType)),
+			NewOptionalProperty("eventTimeStamps", ArrayOfP(NewTimeStamp, 3, 0)),
+			NewOptionalProperty("eventMessageTexts", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventMessageTextsConfig", ArrayOfP(NewCharacterString, 3, 0)),
+			NewOptionalProperty("eventDetectionEnable", V2P(NewBoolean)),
+			NewOptionalProperty("eventAlgorithmInhibitRef", V2P(NewObjectPropertyReference)),
+			NewOptionalProperty("eventAlgorithmInhibit", V2P(NewBoolean)),
+			NewOptionalProperty("reliabilityEvaluationInhibit", V2P(NewBoolean)),
+		},
+	}
+	// TODO: @register_object_type
+	return o, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/object/object_WritableProperty.go
similarity index 75%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/object/object_WritableProperty.go
index efbea52..ceb790f 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/object/object_WritableProperty.go
@@ -21,15 +21,12 @@
 
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
-}
-
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
+// TODO: big WIP
+type WritableProperty interface {
+	StandardProperty
 	// TODO: implement me
-	return nil, nil
 }
 
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+func NewWritableProperty(name string, klass func(Args, KWArgs) (PropertyKlass, error), opts ...func(property *_Property)) WritableProperty {
+	panic("impllement me") // TODO: implement me
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/comm_PCI.go b/plc4go/internal/bacnetip/bacgopes/pdu/comm_PCI.go
index e5fbff1..b565152 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/comm_PCI.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/comm_PCI.go
@@ -57,13 +57,13 @@
 
 var _ IPCI = (*__PCI)(nil)
 
-func new__PCI(args Args, kwArgs KWArgs) *__PCI {
+func new__PCI(args Args, kwArgs KWArgs, options ...Option) *__PCI {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
-	i := &__PCI{}
-	i.rootMessage, _ = KWO[spi.Message](kwArgs, KWCompRootMessage, nil)
-	delete(kwArgs, KWCompRootMessage)
+	i := &__PCI{
+		rootMessage: ExtractRootMessage(options),
+	}
 	i.DebugContents = NewDebugContents(i, "pduUserData+", "pduSource", "pduDestination")
 	var myKwargs = make(KWArgs)
 	var otherKwargs = make(KWArgs)
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/comm_PDUData.go b/plc4go/internal/bacnetip/bacgopes/pdu/comm_PDUData.go
index b0d6007..b9744f5 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/comm_PDUData.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/comm_PDUData.go
@@ -54,7 +54,7 @@
 
 var _ PDUData = (*_PDUData)(nil)
 
-func NewPDUData(args Args, kwArgs KWArgs) PDUData {
+func NewPDUData(args Args, kwArgs KWArgs, _ ...Option) PDUData {
 	data, ok := GAO[any](args, 0, nil)
 	if ok {
 		args = args[1:]
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/pdu.go b/plc4go/internal/bacnetip/bacgopes/pdu/pdu.go
index d738e74..df67f86 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/pdu.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/pdu.go
@@ -80,8 +80,11 @@
 	return &AddressTuple[string, uint16]{uint32ToIpv4(ip).String(), port}
 }
 
+// TODO: convert to struct
 func NewLocalStation(addr any, route *Address) (*Address, error) {
-	l := &Address{}
+	l := &Address{
+		_leafName: "LocalStation",
+	}
 	l.AddrType = LOCAL_STATION_ADDRESS
 	l.AddrRoute = route
 
@@ -106,8 +109,11 @@
 	return l, nil
 }
 
+// TODO: convert to struct
 func NewRemoteStation(net *uint16, addr any, route *Address) (*Address, error) {
-	l := &Address{}
+	l := &Address{
+		_leafName: "RemoteStation",
+	}
 	l.AddrType = REMOTE_STATION_ADDRESS
 	l.AddrNet = net
 	l.AddrRoute = route
@@ -134,22 +140,30 @@
 }
 
 func NewLocalBroadcast(route *Address) *Address {
-	l := &Address{}
+	l := &Address{
+		_leafName: "LocalBroadcast",
+	}
 	l.AddrType = LOCAL_BROADCAST_ADDRESS
 	l.AddrRoute = route
 	return l
 }
 
+// TODO: convert to struct
 func NewRemoteBroadcast(net uint16, route *Address) *Address {
-	r := &Address{}
+	r := &Address{
+		_leafName: "RemoteBroadcast",
+	}
 	r.AddrType = REMOTE_BROADCAST_ADDRESS
 	r.AddrNet = &net
 	r.AddrRoute = route
 	return r
 }
 
+// TODO: convert to struct
 func NewGlobalBroadcast(route *Address) *Address {
-	g := &Address{}
+	g := &Address{
+		_leafName: "GlobalBroadcast",
+	}
 	g.AddrType = GLOBAL_BROADCAST_ADDRESS
 	g.AddrRoute = route
 	return g
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address.go b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address.go
index 6146143..c732772 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address.go
@@ -134,13 +134,17 @@
 	AddrPort           *uint16
 	AddrTuple          *AddressTuple[string, uint16]
 	AddrBroadcastTuple *AddressTuple[string, uint16]
+
+	_leafName string
 }
 
 func NewAddress(args Args) (*Address, error) {
 	if _debug != nil {
 		_debug("__init__ %r", args)
 	}
-	a := &Address{}
+	a := &Address{
+		_leafName: "Address", // TODO: usually this is done by extract, we leaf address for now as this would imply changing type to an interface and that is a big change.
+	}
 	a.AddrNet = nil
 	a.AddrAddress = nil
 	a.AddrLen = nil
@@ -800,7 +804,7 @@
 	}
 	switch v {
 	case 'r':
-		_, _ = fmt.Fprintf(s, "<%s %s>", StructName(), a.String())
+		_, _ = fmt.Fprintf(s, "<%s %s>", a._leafName, a.String())
 	case 'v', 's':
 		_, _ = fmt.Fprint(s, a.String())
 	}
@@ -823,6 +827,7 @@
 		CopyPtr(a.AddrPort),
 		a.AddrTuple.deepCopy(),
 		a.AddrBroadcastTuple.deepCopy(),
+		a._leafName,
 	}
 }
 
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address_plc4xgen.go
index 3e376bf..3a0ba7b 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_Address_plc4xgen.go
@@ -106,6 +106,10 @@
 			return err
 		}
 	}
+
+	if err := writeBuffer.WriteString("_leafName", uint32(len(d._leafName)*8), d._leafName); err != nil {
+		return err
+	}
 	if err := writeBuffer.PopContext("Address"); err != nil {
 		return err
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PCI.go b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PCI.go
index 90f1f4d..652471f 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PCI.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PCI.go
@@ -45,7 +45,7 @@
 
 var _ PCI = (*_PCI)(nil)
 
-func NewPCI(args Args, kwArgs KWArgs) *_PCI {
+func NewPCI(args Args, kwArgs KWArgs, options ...Option) *_PCI {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
@@ -70,7 +70,7 @@
 	expectingReply, _ := KWO(kwArgs, KWPCIExpectingReply, false)
 	networkPriority, _ := KWO(kwArgs, KWPCINetworkPriority, model.NPDUNetworkPriority_NORMAL_MESSAGE)
 	i := &_PCI{
-		new__PCI(args, kwArgs),
+		new__PCI(args, kwArgs, options...),
 		expectingReply,
 		networkPriority,
 	}
diff --git a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PDU.go b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PDU.go
index 96c9a49..6d1bbab 100644
--- a/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PDU.go
+++ b/plc4go/internal/bacnetip/bacgopes/pdu/pdu_PDU.go
@@ -39,13 +39,13 @@
 	*DefaultRFormatter
 }
 
-func NewPDU(args Args, kwArgs KWArgs) PDU {
+func NewPDU(args Args, kwArgs KWArgs, options ...Option) PDU {
 	if _debug != nil {
 		_debug("__init__ %r %r", args, kwArgs)
 	}
 	p := &_PDU{}
-	p._PCI = NewPCI(args, kwArgs)
-	p._PDUData = NewPDUData(args, kwArgs).(*_PDUData)
+	p._PCI = NewPCI(args, kwArgs, options...)
+	p._PDUData = NewPDUData(args, kwArgs, options...).(*_PDUData)
 	p.DefaultRFormatter = NewDefaultRFormatter(p._PCI, p._PDUData)
 	return p
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_Tag.go b/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_Tag.go
index 411c080..922b7ff 100644
--- a/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_Tag.go
+++ b/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_Tag.go
@@ -21,55 +21,60 @@
 
 import (
 	"bytes"
+	"fmt"
+	"io"
+	"strings"
 
 	"github.com/pkg/errors"
 
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
-	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
+	readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 )
 
 const (
 	// Deprecated: use model.TagClass_APPLICATION_TAGS
-	TagApplicationTagClass = model.TagClass_APPLICATION_TAGS
+	TagApplicationTagClass = readWriteModel.TagClass_APPLICATION_TAGS
 	// Deprecated: use model.TagClass_CONTEXT_SPECIFIC_TAGS
-	TagContextTagClass = model.TagClass_CONTEXT_SPECIFIC_TAGS
+	TagContextTagClass = readWriteModel.TagClass_CONTEXT_SPECIFIC_TAGS
 	TagOpeningTagClass = 2
 	TagClosingTagClass = 3
 
 	// Deprecated: use  model.BACnetDataType_NULL
-	TagNullAppTag = model.BACnetDataType_NULL
+	TagNullAppTag = readWriteModel.BACnetDataType_NULL
 	// Deprecated: use  model.BACnetDataType_BOOLEAN
-	TagBooleanAppTag = model.BACnetDataType_BOOLEAN
+	TagBooleanAppTag = readWriteModel.BACnetDataType_BOOLEAN
 	// Deprecated: use  model.BACnetDataType_UNSIGNED_INTEGER
-	TagUnsignedAppTag = model.BACnetDataType_UNSIGNED_INTEGER
+	TagUnsignedAppTag = readWriteModel.BACnetDataType_UNSIGNED_INTEGER
 	// Deprecated: use  model.BACnetDataType_SIGNED_INTEGER
-	TagIntegerAppTag = model.BACnetDataType_SIGNED_INTEGER
+	TagIntegerAppTag = readWriteModel.BACnetDataType_SIGNED_INTEGER
 	// Deprecated: use  model.BACnetDataType_REAL
-	TagRealAppTag = model.BACnetDataType_REAL
+	TagRealAppTag = readWriteModel.BACnetDataType_REAL
 	// Deprecated: use  model.BACnetDataType_DOUBLE
-	TagDoubleAppTag = model.BACnetDataType_DOUBLE
+	TagDoubleAppTag = readWriteModel.BACnetDataType_DOUBLE
 	// Deprecated: use  model.BACnetDataType_OCTET_STRING
-	TagOctetStringAppTag = model.BACnetDataType_OCTET_STRING
+	TagOctetStringAppTag = readWriteModel.BACnetDataType_OCTET_STRING
 	// Deprecated: use  model.BACnetDataType_CHARACTER_STRING
-	TagCharacterStringAppTag = model.BACnetDataType_CHARACTER_STRING
+	TagCharacterStringAppTag = readWriteModel.BACnetDataType_CHARACTER_STRING
 	// Deprecated: use  model.BACnetDataType_BIT_STRING
-	TagBitStringAppTag = model.BACnetDataType_BIT_STRING
+	TagBitStringAppTag = readWriteModel.BACnetDataType_BIT_STRING
 	// Deprecated: use  model.BACnetDataType_ENUMERATED
-	TagEnumeratedAppTag = model.BACnetDataType_ENUMERATED
+	TagEnumeratedAppTag = readWriteModel.BACnetDataType_ENUMERATED
 	// Deprecated: use  model.BACnetDataType_DATE
-	TagDateAppTag = model.BACnetDataType_DATE
+	TagDateAppTag = readWriteModel.BACnetDataType_DATE
 	// Deprecated: use  model.BACnetDataType_TIME
-	TagTimeAppTag = model.BACnetDataType_TIME
+	TagTimeAppTag = readWriteModel.BACnetDataType_TIME
 	// Deprecated: use  model.BACnetDataType_BACNET_OBJECT_IDENTIFIER
-	TagObjectIdentifierAppTag = model.BACnetDataType_BACNET_OBJECT_IDENTIFIER
+	TagObjectIdentifierAppTag = readWriteModel.BACnetDataType_BACNET_OBJECT_IDENTIFIER
 	TagReservedAppTag13       = 13
 	TagReservedAppTag14       = 14
 	TagReservedAppTag15       = 15
 )
 
 type Tag interface {
-	GetTagClass() model.TagClass
+	DebugContentPrinter
+	GetTagClass() readWriteModel.TagClass
 	GetTagNumber() uint
 	GetTagLvt() int
 	GetTagData() []byte
@@ -83,7 +88,7 @@
 }
 
 type tag struct {
-	tagClass  model.TagClass
+	tagClass  readWriteModel.TagClass
 	tagNumber uint
 	tagLVT    int
 	tagData   []byte
@@ -92,6 +97,8 @@
 	appTagClass []any
 }
 
+var _ Tag = (*tag)(nil)
+
 func NewTag(args Args) (Tag, error) {
 	t := &tag{
 		appTagName: []string{
@@ -129,7 +136,7 @@
 	}
 
 	// extract the type
-	t.tagClass = model.TagClass(tag >> 3 & 0x01)
+	t.tagClass = readWriteModel.TagClass(tag >> 3 & 0x01)
 
 	// extract the tag number
 	t.tagNumber = uint(tag >> 4)
@@ -170,7 +177,7 @@
 		t.tagLVT = 0
 	}
 
-	if t.tagClass == model.TagClass_APPLICATION_TAGS && t.tagNumber == uint(model.BACnetDataType_BOOLEAN) {
+	if t.tagClass == readWriteModel.TagClass_APPLICATION_TAGS && t.tagNumber == uint(readWriteModel.BACnetDataType_BOOLEAN) {
 		// tagLVT contains value
 		t.tagData = nil
 	} else {
@@ -186,7 +193,7 @@
 func (t *tag) Encode(pdu PDUData) {
 	var data byte
 	// check for special encoding
-	if t.tagClass == model.TagClass_CONTEXT_SPECIFIC_TAGS {
+	if t.tagClass == readWriteModel.TagClass_CONTEXT_SPECIFIC_TAGS {
 		data = 0x08
 	} else if t.tagClass == TagOpeningTagClass {
 		data = 0x0E
@@ -234,27 +241,27 @@
 }
 
 func (t *tag) AppToContext(context uint) (*ContextTag, error) {
-	if t.tagClass != model.TagClass_APPLICATION_TAGS {
+	if t.tagClass != readWriteModel.TagClass_APPLICATION_TAGS {
 		return nil, errors.New("application tag required")
 	}
-	if t.tagNumber == uint(model.BACnetDataType_BOOLEAN) {
+	if t.tagNumber == uint(readWriteModel.BACnetDataType_BOOLEAN) {
 		return NewContextTag(NA(context, []byte{byte(t.tagLVT)}))
 	}
 	return NewContextTag(NA(context, t.tagData))
 }
 
 func (t *tag) ContextToApp(dataType uint) (Tag, error) {
-	if t.tagClass != model.TagClass_CONTEXT_SPECIFIC_TAGS {
+	if t.tagClass != readWriteModel.TagClass_CONTEXT_SPECIFIC_TAGS {
 		return nil, errors.New("context tag required")
 	}
-	if dataType == uint(model.BACnetDataType_BOOLEAN) {
-		return NewTag(NA(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_BOOLEAN, t.tagData[0], nil))
+	if dataType == uint(readWriteModel.BACnetDataType_BOOLEAN) {
+		return NewTag(NA(readWriteModel.TagClass_APPLICATION_TAGS, readWriteModel.BACnetDataType_BOOLEAN, t.tagData[0], nil))
 	}
 	return NewApplicationTag(NA(dataType, t.tagData))
 }
 
 func (t *tag) AppToObject() (any, error) {
-	if t.tagClass != model.TagClass_APPLICATION_TAGS {
+	if t.tagClass != readWriteModel.TagClass_APPLICATION_TAGS {
 		return nil, errors.New("context tag required")
 	}
 
@@ -297,19 +304,19 @@
 
 func (t *tag) set(args Args) {
 	switch tagClass := args[0].(type) {
-	case model.TagClass:
+	case readWriteModel.TagClass:
 		t.tagClass = tagClass
 	case uint:
-		t.tagClass = model.TagClass(tagClass)
+		t.tagClass = readWriteModel.TagClass(tagClass)
 	case uint8:
-		t.tagClass = model.TagClass(tagClass)
+		t.tagClass = readWriteModel.TagClass(tagClass)
 	case int:
-		t.tagClass = model.TagClass(tagClass)
+		t.tagClass = readWriteModel.TagClass(tagClass)
 	default:
 		panic("oh no")
 	}
 	switch tagNumber := args[1].(type) {
-	case model.BACnetDataType:
+	case readWriteModel.BACnetDataType:
 		t.tagNumber = uint(tagNumber)
 	case uint:
 		t.tagNumber = tagNumber
@@ -348,13 +355,13 @@
 }
 
 func (t *tag) setAppData(tagNumber uint, tdata []byte) {
-	t.tagClass = model.TagClass_APPLICATION_TAGS
+	t.tagClass = readWriteModel.TagClass_APPLICATION_TAGS
 	t.tagNumber = tagNumber
 	t.tagLVT = len(tdata)
 	t.tagData = tdata
 }
 
-func (t *tag) GetTagClass() model.TagClass {
+func (t *tag) GetTagClass() readWriteModel.TagClass {
 	return t.tagClass
 }
 
@@ -386,3 +393,60 @@
 		t.tagLVT == otherTag.GetTagLvt() &&
 		bytes.Equal(t.tagData, otherTag.GetTagData())
 }
+
+func (t *tag) Format(s fmt.State, v rune) {
+	switch v {
+	case 'r':
+		sname := StructName() // TODO: maybe use leafname too
+		var desc string
+		if t.tagClass == TagOpeningTagClass {
+			desc = fmt.Sprintf("(open(%d))", t.tagNumber)
+		} else if t.tagClass == TagClosingTagClass {
+			desc = fmt.Sprintf("(close(%d))", t.tagNumber)
+		} else if t.tagClass == readWriteModel.TagClass_CONTEXT_SPECIFIC_TAGS {
+			desc = fmt.Sprintf("(context(%d))", t.tagNumber)
+		} else if t.tagClass == readWriteModel.TagClass_APPLICATION_TAGS && t.tagNumber < uint(len(t.appTagName)) {
+			desc = fmt.Sprintf("(%s)", t.appTagName[t.tagNumber])
+		} else {
+			desc = "(?)"
+		}
+
+		_, _ = fmt.Fprintf(s, "<%s%s instance at %p", sname, desc, t)
+	}
+}
+
+func (t *tag) PrintDebugContents(indent int, file io.Writer, _ids []uintptr) {
+	// object reference first
+	_, _ = fmt.Fprintf(file, "%s%r\n", strings.Repeat("    ", indent), t)
+	indent += 1
+
+	// tag class
+	msg := fmt.Sprintf("%stagClass = %s ", strings.Repeat("    ", indent), t.tagClass)
+	if t.tagClass == readWriteModel.TagClass_APPLICATION_TAGS {
+		msg += "application"
+	} else if t.tagClass == readWriteModel.TagClass_CONTEXT_SPECIFIC_TAGS {
+		msg += "context"
+	} else if t.tagClass == TagOpeningTagClass {
+		msg += "opening"
+	} else if t.tagClass == TagClosingTagClass {
+		msg += "closing"
+	} else {
+		msg += "?"
+	}
+	_, _ = fmt.Fprintf(file, msg+"\n")
+
+	// tag number
+	msg = fmt.Sprintf("%stagNumber = %d ", strings.Repeat("    ", indent), t.tagNumber)
+	if t.tagClass == readWriteModel.TagClass_APPLICATION_TAGS && t.tagNumber < uint(len(t.appTagName)) {
+		msg += t.appTagName[t.tagNumber]
+	} else {
+		msg += "?"
+	}
+	_, _ = fmt.Fprintf(file, msg+"\n")
+
+	// length, value, type
+	_, _ = fmt.Fprintf(file, "%stagLVT = %d\n", strings.Repeat("    ", indent), t.tagLVT)
+
+	// data
+	_, _ = fmt.Fprintf(file, "%stagData = '%s'\n", strings.Repeat("    ", indent), Btox(t.tagData, "."))
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_TagList.go b/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_TagList.go
index cdef57f..eb7ab3e 100644
--- a/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_TagList.go
+++ b/plc4go/internal/bacnetip/bacgopes/primitivedata/primitivedata_TagList.go
@@ -20,19 +20,25 @@
 package primitivedata
 
 import (
+	"io"
+
 	"github.com/pkg/errors"
 
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 )
 
 type TagList struct {
+	*DefaultRFormatter
 	tagList []Tag
 }
 
 func NewTagList(arg Arg) *TagList {
-	t := &TagList{}
+	t := &TagList{
+		DefaultRFormatter: NewDefaultRFormatter(),
+	}
 	switch arg := arg.(type) {
 	case []any:
 		args := arg
@@ -172,3 +178,9 @@
 func (b *TagList) GetTagList() []Tag {
 	return b.tagList
 }
+
+func (b *TagList) PrintDebugContents(indent int, file io.Writer, _ids []uintptr) {
+	for _, tag := range b.tagList {
+		tag.PrintDebugContents(indent, file, _ids)
+	}
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/service/cov_ActiveCOVSubscription.go b/plc4go/internal/bacnetip/bacgopes/service/cov_ActiveCOVSubscription.go
index 39d7470..52e55d6 100644
--- a/plc4go/internal/bacnetip/bacgopes/service/cov_ActiveCOVSubscription.go
+++ b/plc4go/internal/bacnetip/bacgopes/service/cov_ActiveCOVSubscription.go
@@ -22,6 +22,6 @@
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
 
 type ActiveCOVSubscription struct {
-	*Property
+	Property
 	//TODO: implement me
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices.go b/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices.go
index f2fe1ee..06fbc8a 100644
--- a/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices.go
@@ -44,7 +44,7 @@
 	_requirements WhoIsIAmServicesRequirements `ignore:"true"`
 	Capability
 
-	localDevice *LocalDeviceObject
+	localDevice LocalDeviceObject
 
 	log zerolog.Logger
 }
@@ -70,7 +70,7 @@
 	return w, nil
 }
 
-func WithWhoIsIAmServicesLocalDevice(localDevice *LocalDeviceObject) func(*WhoIsIAmServices) {
+func WithWhoIsIAmServicesLocalDevice(localDevice LocalDeviceObject) func(*WhoIsIAmServices) {
 	return func(w *WhoIsIAmServices) {
 		w.localDevice = localDevice
 	}
@@ -92,7 +92,21 @@
 	}
 	w.log.Debug().Msg("WhoIs")
 
-	var deviceInstanceRangeLowLimit, deviceInstanceRangeHighLimit uint
+	// build a request
+	whoIs, err := NewWhoIsRequest(Nothing())
+	if err != nil {
+		return errors.Wrap(err, "NewWhoIsRequest failed")
+	}
+
+	// defaults to a global broadcast
+	if address == nil {
+		address = NewGlobalBroadcast(nil)
+	}
+
+	// set the destination
+	whoIs.SetPDUDestination(address)
+
+	//check for consistent parameters
 	if lowLimit != nil {
 		if highLimit == nil {
 			return errors.New("highLimit required")
@@ -102,7 +116,7 @@
 		}
 
 		// low limit is fine
-		deviceInstanceRangeLowLimit = *lowLimit
+		whoIs.SetDeviceInstanceRangeLowLimit(*lowLimit)
 	}
 	if highLimit != nil {
 		if lowLimit == nil {
@@ -113,18 +127,15 @@
 		}
 
 		// low limit is fine
-		deviceInstanceRangeHighLimit = *highLimit
+		whoIs.SetDeviceInstanceRangeHighLimit(*highLimit)
 	}
 
-	// Build a request
-	whoIs := readWriteModel.NewBACnetUnconfirmedServiceRequestWhoIs(readWriteModel.CreateBACnetContextTagUnsignedInteger(0, deviceInstanceRangeLowLimit), readWriteModel.CreateBACnetContextTagUnsignedInteger(1, deviceInstanceRangeHighLimit), 0)
-
 	if _debug != nil {
 		_debug("    - whoIs: %r", whoIs)
 	}
 	w.log.Debug().Stringer("whoIs", whoIs).Msg("WhoIs")
 
-	return w._requirements.Request(NA(NewPDU(NoArgs, NKW(KWCompRootMessage, whoIs, KWCPCIDestination, address))), NoKWArgs())
+	return w._requirements.Request(NA(whoIs), NoKWArgs())
 }
 
 // DoWhoIsRequest respond to a Who-Is request.
@@ -176,12 +187,12 @@
 
 	// see we should respond
 	if lowLimit != nil {
-		if uint(w.localDevice.ObjectIdentifier[1]) < *lowLimit {
+		if uint(w.localDevice.GetObjectIdentifier()[1]) < *lowLimit {
 			return nil
 		}
 	}
 	if highLimit != nil {
-		if uint(w.localDevice.ObjectIdentifier[1]) > *highLimit {
+		if uint(w.localDevice.GetObjectIdentifier()[1]) > *highLimit {
 			return nil
 		}
 	}
@@ -208,10 +219,10 @@
 	iAm, err := NewIAmRequest(
 		NoArgs,
 		NKW(
-			KnownKey("iAmDeviceIdentifier"), w.localDevice.ObjectIdentifier,
-			KnownKey("maxAPDULengthAccepted"), w.localDevice.MaximumApduLengthAccepted,
-			KnownKey("segmentationSupported"), w.localDevice.SegmentationSupported,
-			KnownKey("vendorID"), w.localDevice.VendorIdentifier,
+			KnownKey("iAmDeviceIdentifier"), w.localDevice.GetObjectIdentifier(),
+			KnownKey("maxAPDULengthAccepted"), w.localDevice.GetMaximumApduLengthAccepted(),
+			KnownKey("segmentationSupported"), w.localDevice.GetSegmentationSupported(),
+			KnownKey("vendorID"), w.localDevice.GetVendorIdentifier(),
 		),
 	)
 	if err != nil {
@@ -226,7 +237,7 @@
 	if _debug != nil {
 		_debug("    - iAm: %r", iAm)
 	}
-	w.log.Debug().Stringer("iAm", iAm).Msg("IAm")
+	w.log.Debug().Stringer("iAm", iAm).Msg("")
 
 	return w._requirements.Request(NA(iAm), NoKWArgs())
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices_plc4xgen.go
index df90f2a..8945418 100644
--- a/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/service/service_device_WhoIsIAmServices_plc4xgen.go
@@ -51,13 +51,11 @@
 	if err := d.Capability.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
 		return err
 	}
-	if d.localDevice != nil {
-		{
-			_value := fmt.Sprintf("%v", d.localDevice)
+	{
+		_value := fmt.Sprintf("%v", d.localDevice)
 
-			if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
+		if err := writeBuffer.WriteString("localDevice", uint32(len(_value)*8), _value); err != nil {
+			return err
 		}
 	}
 	if err := writeBuffer.PopContext("WhoIsIAmServices"); err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices.go
similarity index 96%
rename from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
rename to plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices.go
index efbea52..8c56f11 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices.go
@@ -17,11 +17,11 @@
  * under the License.
  */
 
-package object
+package service
 
 import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
+//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=service_object_
 type ReadWritePropertyServices struct {
 }
 
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices_plc4xgen.go
similarity index 96%
rename from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices_plc4xgen.go
rename to plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices_plc4xgen.go
index a86a8ad..5b195bc 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/service/service_object_ReadWritePropertyServices_plc4xgen.go
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-// Code generated by "plc4xGenerator -type=ReadWritePropertyServices -prefix=object_"; DO NOT EDIT.
+// Code generated by "plc4xGenerator -type=ReadWritePropertyServices -prefix=service_object_"; DO NOT EDIT.
 
-package object
+package service
 
 import (
 	"context"
diff --git a/plc4go/internal/bacnetip/bacgopes/task/task_Task_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/task/task_Task_plc4xgen.go
index c77cbfb..4d24648 100644
--- a/plc4go/internal/bacnetip/bacgopes/task/task_Task_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/task/task_Task_plc4xgen.go
@@ -48,9 +48,10 @@
 	if err := writeBuffer.PushContext("Task"); err != nil {
 		return err
 	}
-
-	if err := writeBuffer.WriteString("taskTime", uint32(len(fmt.Sprintf("%s", d.taskTime))*8), fmt.Sprintf("%s", d.taskTime)); err != nil {
-		return err
+	if d.taskTime != nil {
+		if err := writeBuffer.WriteString("taskTime", uint32(len(fmt.Sprintf("%s", *d.taskTime))*8), fmt.Sprintf("%s", *d.taskTime)); err != nil {
+			return err
+		}
 	}
 
 	if err := writeBuffer.WriteBit("isScheduled", d.isScheduled); err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/task/task_taskItem_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/task/task_taskItem_plc4xgen.go
index 714c29e..60c5ecd 100644
--- a/plc4go/internal/bacnetip/bacgopes/task/task_taskItem_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/task/task_taskItem_plc4xgen.go
@@ -48,9 +48,10 @@
 	if err := writeBuffer.PushContext("taskItem"); err != nil {
 		return err
 	}
-
-	if err := writeBuffer.WriteString("taskTime", uint32(len(fmt.Sprintf("%s", d.taskTime))*8), fmt.Sprintf("%s", d.taskTime)); err != nil {
-		return err
+	if d.taskTime != nil {
+		if err := writeBuffer.WriteString("taskTime", uint32(len(fmt.Sprintf("%s", *d.taskTime))*8), fmt.Sprintf("%s", *d.taskTime)); err != nil {
+			return err
+		}
 	}
 
 	if err := writeBuffer.WriteInt64("id", 64, int64(d.id)); err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachine.go
index 922de8f..4e013a2 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachine.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachine.go
@@ -91,7 +91,7 @@
 
 	states                 []State
 	name                   string
-	machineGroup           *StateMachineGroup
+	machineGroup           *StateMachineGroup `asPtr:"true"`
 	stateSubStruct         any
 	startState             State
 	unexpectedReceiveState State
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup.go b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup.go
index 1c901ed..b9e196c 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup.go
@@ -34,6 +34,8 @@
 //	    are expecting to receive one or more tPDU's first before the ones
 //	    that send tPDU's.  They will be started first, and be ready for the
 //	    tPDU that might be sent.
+//
+//go:generate plc4xGenerator -type=StateMachineGroup -prefix=state_machine_
 type StateMachineGroup struct {
 	stateMachines  []StateMachine
 	isSuccessState bool
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup_plc4xgen.go
new file mode 100644
index 0000000..be5f5cf
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_StateMachineGroup_plc4xgen.go
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Code generated by "plc4xGenerator -type=StateMachineGroup -prefix=state_machine_"; DO NOT EDIT.
+
+package state_machine
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+var _ = fmt.Printf
+
+func (d *StateMachineGroup) Serialize() ([]byte, error) {
+	if d == nil {
+		return nil, fmt.Errorf("(*DeviceInfoCache)(nil)")
+	}
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (d *StateMachineGroup) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	if d == nil {
+		return fmt.Errorf("(*DeviceInfoCache)(nil)")
+	}
+	if err := writeBuffer.PushContext("StateMachineGroup"); err != nil {
+		return err
+	}
+	if err := writeBuffer.PushContext("stateMachines", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+	for _, elem := range d.stateMachines {
+		_value := fmt.Sprintf("%v", elem)
+
+		if err := writeBuffer.WriteString("stateMachines", uint32(len(_value)*8), _value); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PopContext("stateMachines", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("isSuccessState", d.isSuccessState); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("isFailState", d.isFailState); err != nil {
+		return err
+	}
+	if err := writeBuffer.PushContext("events", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+	for _name, elem := range d.events {
+		name := _name
+		_value := fmt.Sprintf("%v", elem)
+
+		if err := writeBuffer.WriteString(name, uint32(len(_value)*8), _value); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.PopContext("events", utils.WithRenderAsList(true)); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("startupFlag", d.startupFlag); err != nil {
+		return err
+	}
+
+	if err := writeBuffer.WriteBit("isRunning", d.isRunning); err != nil {
+		return err
+	}
+	if err := writeBuffer.PopContext("StateMachineGroup"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *StateMachineGroup) String() string {
+	if alternateStringer, ok := any(d).(utils.AlternateStringer); ok {
+		if alternateString, use := alternateStringer.AlternateString(); use {
+			return alternateString
+		}
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_stateMachine_plc4xgen.go b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_stateMachine_plc4xgen.go
index 3e53cde..d80fade 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_stateMachine_plc4xgen.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/state_machine/state_machine_stateMachine_plc4xgen.go
@@ -73,14 +73,9 @@
 	if err := writeBuffer.WriteString("name", uint32(len(d.name)*8), d.name); err != nil {
 		return err
 	}
-	if d.machineGroup != nil {
-		{
-			_value := fmt.Sprintf("%v", d.machineGroup)
 
-			if err := writeBuffer.WriteString("machineGroup", uint32(len(_value)*8), _value); err != nil {
-				return err
-			}
-		}
+	if err := writeBuffer.WriteString("machineGroup", uint32(len(fmt.Sprintf("%p", d.machineGroup))*8), fmt.Sprintf("%p", d.machineGroup)); err != nil {
+		return err
 	}
 	{
 		_value := fmt.Sprintf("%v", d.stateSubStruct)
@@ -128,9 +123,10 @@
 			return err
 		}
 	}
-
-	if err := writeBuffer.WriteString("stateMachineTimeout", uint32(len(fmt.Sprintf("%s", d.stateMachineTimeout))*8), fmt.Sprintf("%s", d.stateMachineTimeout)); err != nil {
-		return err
+	if d.stateMachineTimeout != nil {
+		if err := writeBuffer.WriteString("stateMachineTimeout", uint32(len(fmt.Sprintf("%s", *d.stateMachineTimeout))*8), fmt.Sprintf("%s", *d.stateMachineTimeout)); err != nil {
+			return err
+		}
 	}
 	if d.timeoutTask != nil {
 		{
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers.go b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers.go
index 309be6e..e7a8679 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers.go
@@ -27,5 +27,5 @@
 var _debug = CreateDebugPrinter()
 
 type TestDeviceObject struct {
-	*LocalDeviceObject
+	LocalDeviceObject
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPBBMDApplication.go b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPBBMDApplication.go
index 3e539aa..7be5836 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPBBMDApplication.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPBBMDApplication.go
@@ -32,7 +32,6 @@
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/service"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
@@ -72,11 +71,14 @@
 
 	// build a local device object
 	localDevice := &TestDeviceObject{
-		LocalDeviceObject: &LocalDeviceObject{
-			ObjectName:       b.name,
-			ObjectIdentifier: "device:999",
-			VendorIdentifier: 999,
-		},
+		LocalDeviceObject: NewLocalDeviceObject(
+			NoArgs,
+			NKW(
+				KWObjectName, b.name,
+				KWObjectIdentifier, "device:999",
+				KWVendorIdentifier, 999,
+			),
+		),
 	}
 
 	// continue with initialization
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPSimpleApplicationLayerStateMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPSimpleApplicationLayerStateMachine.go
index 9a9903a..6fd99d7 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPSimpleApplicationLayerStateMachine.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_BIPSimpleApplicationLayerStateMachine.go
@@ -66,11 +66,14 @@
 
 	// build a local device object
 	localDevice := &TestDeviceObject{
-		LocalDeviceObject: &LocalDeviceObject{
-			ObjectName:       b.name,
-			ObjectIdentifier: "device:998",
-			VendorIdentifier: 999,
-		},
+		LocalDeviceObject: NewLocalDeviceObject(
+			NoArgs,
+			NKW(
+				KWObjectName, b.name,
+				KWObjectIdentifier, "device:998",
+				KWVendorIdentifier, 999,
+			),
+		),
 	}
 
 	// continue with initialization
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_FauxMultiplexer.go b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_FauxMultiplexer.go
index 257f693..e0533bb 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_FauxMultiplexer.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_bvll/helpers_FauxMultiplexer.go
@@ -144,5 +144,5 @@
 		dest = pdu.GetPDUDestination()
 	}
 
-	return s.Response(NA(NewPDU(NA(pdu), NKW(KWCompRootMessage, pdu, KWCPCISource, src, KWCPCIDestination, dest))), NoKWArgs())
+	return s.Response(NA(NewPDU(NA(pdu), NKW(KWCPCISource, src, KWCPCIDestination, dest))), NoKWArgs())
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers.go
index 73b7326..21f056e 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers.go
@@ -20,534 +20,9 @@
 package test_network
 
 import (
-	"fmt"
-
-	"github.com/pkg/errors"
-	"github.com/rs/zerolog"
-
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/app"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/appservice"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/npdu"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/object"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/service"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/tests/state_machine"
-	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
 )
 
-type _NetworkServiceElement struct {
-	*NetworkServiceElement
-}
-
-func new_NetworkServiceElement(localLog zerolog.Logger) (*_NetworkServiceElement, error) {
-	i := &_NetworkServiceElement{}
-
-	// This class turns off the deferred startup function call that broadcasts
-	// I-Am-Router-To-Network and Network-Number-Is messages.
-	var err error
-	i.NetworkServiceElement, err = NewNetworkServiceElement(localLog, WithNetworkServiceElementStartupDisabled(true))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service element")
-	}
-	return i, nil
-}
-
-//go:generate plc4xGenerator -type=NPDUCodec -prefix=helpers_
-type NPDUCodec struct {
-	ClientContract
-	ServerContract
-
-	log zerolog.Logger
-}
-
-func NewNPDUCodec(localLog zerolog.Logger) (*NPDUCodec, error) {
-	n := &NPDUCodec{
-		log: localLog,
-	}
-	var err error
-	n.ClientContract, err = NewClient(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating client")
-	}
-	n.ServerContract, err = NewServer(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating client")
-	}
-	if !LogTestNetwork {
-		n.log = zerolog.Nop()
-	}
-	return n, nil
-}
-
-func (n *NPDUCodec) Indication(args Args, kwArgs KWArgs) error {
-	n.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
-
-	npdu := GA[NPDU](args, 0)
-
-	// first a generic _NPDU
-	xpdu, err := NewNPDU(Nothing())
-	if err != nil {
-		return errors.Wrap(err, "error creating NPDU")
-	}
-	if err := npdu.Encode(xpdu); err != nil {
-		return errors.Wrap(err, "error encoding xpdu")
-	}
-
-	// Now as a vanilla PDU
-	ypdu := NewPDU(Nothing())
-	if err := xpdu.Encode(ypdu); err != nil {
-		return errors.Wrap(err, "error decoding xpdu")
-	}
-	n.log.Debug().Stringer("ypdu", ypdu).Msg("encoded")
-
-	// send it downstream
-	return n.Request(NA(ypdu), NoKWArgs())
-}
-
-func (n *NPDUCodec) Confirmation(args Args, kwArgs KWArgs) error {
-	n.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
-
-	pdu := GA[PDU](args, 0)
-
-	// decode as generic _NPDU
-	xpdu, err := NewNPDU(Nothing())
-	if err != nil {
-		return errors.Wrap(err, "error creating NPDU")
-	}
-	if err := xpdu.Decode(pdu); err != nil {
-		return errors.Wrap(err, "error decoding xpdu")
-	}
-
-	// drop application layer message
-	if xpdu.GetNPDUNetMessage() == nil {
-		n.log.Trace().Msg("drop message")
-		return nil
-	}
-
-	// do a deeper decode of the _NPDU
-	ypdu := NPDUTypes[*xpdu.GetNPDUNetMessage()]()
-	if err := ypdu.Decode(xpdu); err != nil {
-		return errors.Wrap(err, "error decoding ypdu")
-	}
-
-	return n.Response(NA(ypdu), NoKWArgs())
-}
-
-type SnifferStateMachine struct {
-	*ClientStateMachine
-
-	address *Address
-	node    *Node
-
-	log zerolog.Logger
-}
-
-func NewSnifferStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*SnifferStateMachine, error) {
-	s := &SnifferStateMachine{
-		log: localLog,
-	}
-	var err error
-	s.ClientStateMachine, err = NewClientStateMachine(s.log, WithClientStateMachineName(address), WithClientStateMachineExtension(s))
-	if err != nil {
-		return nil, errors.Wrap(err, "error building client state machine")
-	}
-
-	// save the name and address
-	s.address, err = NewAddress(NA(address))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating address")
-	}
-
-	// create a promiscuous node, added to the network
-	s.node, err = NewNode(s.log, s.address, WithNodePromiscuous(true), WithNodeLan(vlan))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating node")
-	}
-	if LogTestNetwork {
-		s.log.Debug().Stringer("node", s.node).Msg("node")
-	}
-
-	// bind the stack together
-	if err := Bind(s.log, s, s.node); err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	if !LogTestNetwork {
-		s.log = zerolog.Nop()
-	}
-	return s, nil
-}
-
-type NetworkLayerStateMachine struct {
-	*ClientStateMachine
-
-	address *Address
-
-	log   zerolog.Logger
-	codec *NPDUCodec
-	node  *Node
-}
-
-func NewNetworkLayerStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*NetworkLayerStateMachine, error) {
-	n := &NetworkLayerStateMachine{
-		log: localLog,
-	}
-	var err error
-	n.ClientStateMachine, err = NewClientStateMachine(localLog, WithClientStateMachineName(address), WithClientStateMachineExtension(n))
-	if err != nil {
-		return nil, errors.Wrap(err, "error building client state machine")
-	}
-
-	// save the name and address
-	n.address, err = NewAddress(NA(address))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creaing address")
-	}
-
-	// create a network layer encoder/decoder
-	n.codec, err = NewNPDUCodec(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating codec")
-	}
-	if LogTestNetwork {
-		n.log.Debug().Stringer("codec", n.codec).Msg("codec")
-	}
-
-	// create a node, added to the network
-	n.node, err = NewNode(localLog, n.address, WithNodeLan(vlan))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating node")
-	}
-	if LogTestNetwork {
-		n.log.Debug().Stringer("node", n.node).Msg("node")
-	}
-
-	// bind this to the node
-	if err := Bind(localLog, n, n.codec, n.node); err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-	if !LogTestNetwork {
-		n.log = zerolog.Nop()
-	}
-	return n, nil
-}
-
-type RouterNode struct {
-	nsap *NetworkServiceAccessPoint
-	nse  *_NetworkServiceElement
-
-	log zerolog.Logger
-}
-
-func NewRouterNode(localLog zerolog.Logger) (*RouterNode, error) {
-	r := &RouterNode{log: localLog}
-	var err error
-	// a network service access point will be needed
-	r.nsap, err = NewNetworkServiceAccessPoint(r.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service access point")
-	}
-	// give the NSAP a generic network layer service element
-	r.nse, err = new_NetworkServiceElement(r.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service element")
-	}
-	err = Bind(r.log, r.nse, r.nsap)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-	if !LogTestNetwork {
-		r.log = zerolog.Nop()
-	}
-	return r, nil
-}
-
-func (r *RouterNode) AddNetwork(address string, vlan *Network, net uint16) error {
-	r.log.Debug().Str("address", address).Stringer("vlan", vlan).Uint16("net", net).Msg("AddNetwork")
-
-	// convert the address to an Address
-	addr, err := NewAddress(NA(address))
-	if err != nil {
-		return errors.Wrap(err, "error creaing address")
-	}
-
-	// create a node, add to the network
-	node, err := NewNode(r.log, addr, WithNodeLan(vlan))
-	if err != nil {
-		return errors.Wrap(err, "error creating node")
-	}
-
-	// bind the BIP stack to the local network
-	return r.nsap.Bind(node, &net, addr)
-}
-
-func (r *RouterNode) String() string {
-	return fmt.Sprintf("RouterNode")
-}
-
-type RouterStateMachine struct {
-	*RouterNode
-	StateMachineContract
-}
-
-func NewRouterStateMachine(localLog zerolog.Logger) (*RouterStateMachine, error) {
-	r := &RouterStateMachine{}
-	var err error
-	r.RouterNode, err = NewRouterNode(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating router node")
-	}
-	var initFunc func()
-	r.StateMachineContract, initFunc = NewStateMachine(localLog, r)
-	initFunc()
-	if !LogTestNetwork {
-		r.log = zerolog.Nop()
-	}
-	return r, nil
-}
-
-func (r *RouterStateMachine) Send(args Args, kwArgs KWArgs) error {
-	panic("not available")
-}
-
-func (r *RouterStateMachine) String() string {
-	return "RouterStateMachine"
-}
-
-type TestDeviceObject struct {
-	*LocalDeviceObject
-}
-
-//go:generate plc4xGenerator -type=ApplicationLayerStateMachine -prefix=helpers_
-type ApplicationLayerStateMachine struct {
-	ApplicationServiceElementContract
-	*ClientStateMachine `ignore:"true"` // TODO: add support
-
-	name    string
-	address *Address
-
-	asap *ApplicationServiceAccessPoint
-	smap *StateMachineAccessPoint
-	nsap *NetworkServiceAccessPoint
-	nse  *_NetworkServiceElement
-	node *Node
-
-	log zerolog.Logger
-}
-
-func NewApplicationLayerStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*ApplicationLayerStateMachine, error) {
-	a := &ApplicationLayerStateMachine{
-		log: localLog,
-	}
-
-	// save the name and address
-	a.name = fmt.Sprintf("app @ %s", address)
-	var err error
-	a.address, err = NewAddress(NA(address))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creaing address")
-	}
-
-	// build a local device object
-	localDevice := TestDeviceObject{
-		&LocalDeviceObject{
-			ObjectName:       a.name,
-			ObjectIdentifier: "device:" + address,
-			VendorIdentifier: 999,
-		},
-	}
-
-	if LogTestNetwork {
-		a.log.Debug().Stringer("address", a.address).Msg("address")
-	}
-
-	// continue with initialization
-	a.ApplicationServiceElementContract, err = NewApplicationServiceElement(a.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating application service")
-	}
-	a.ClientStateMachine, err = NewClientStateMachine(a.log, WithClientStateMachineName(localDevice.ObjectName), WithClientStateMachineExtension(a))
-	if err != nil {
-		return nil, errors.Wrap(err, "error building client state machine")
-	}
-
-	// include a application decoder
-	a.asap, err = NewApplicationServiceAccessPoint(a.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating application service access point")
-	}
-
-	// pass the device object to the state machine access point so it
-	// can know if it should support segmentation
-	// the segmentation state machines need access to some device
-	// information cache, usually shared with the application
-	a.smap, err = NewStateMachineAccessPoint(a.log, localDevice.LocalDeviceObject, WithStateMachineAccessPointDeviceInfoCache(NewDeviceInfoCache(a.log))) // TODO: this is not quite right as we unwrap here
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating state machine access point")
-	}
-
-	//  a network service access point will be needed
-	a.nsap, err = NewNetworkServiceAccessPoint(a.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service access point")
-	}
-
-	//  give the NSAP a generic network layer service element
-	a.nse, err = new_NetworkServiceElement(a.log)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service element")
-	}
-	err = Bind(a.log, a.nse, a.nsap)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	//  bind the top layers
-	err = Bind(a.log, a, a.asap, a.smap, a.nsap)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	//  create a node, added to the network
-	a.node, err = NewNode(a.log, a.address, WithNodeLan(vlan))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating node")
-	}
-	if LogTestNetwork {
-		a.log.Debug().Stringer("node", a.node).Msg("node")
-	}
-
-	//  bind the stack to the local network
-	err = a.nsap.Bind(a.node, nil, nil)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	if !LogTestNetwork {
-		a.log = zerolog.Nop()
-	}
-	return a, nil
-}
-
-func (a *ApplicationLayerStateMachine) Indication(args Args, kwArgs KWArgs) error {
-	a.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
-	return a.Receive(args, NoKWArgs())
-}
-
-func (a *ApplicationLayerStateMachine) Confirmation(args Args, kwArgs KWArgs) error {
-	a.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Confirmation")
-	return a.Receive(args, NoKWArgs())
-}
-
-//go:generate plc4xGenerator -type=ApplicationNode -prefix=helpers_
-type ApplicationNode struct {
-	*Application
-	*WhoIsIAmServices
-	*ReadWritePropertyServices
-
-	name    string
-	address *Address `directSerialize:"true"`
-	asap    *ApplicationServiceAccessPoint
-	smap    *StateMachineAccessPoint
-	nsap    *NetworkServiceAccessPoint
-	nse     *_NetworkServiceElement
-	node    *Node
-
-	log zerolog.Logger
-}
-
-func NewApplicationNode(localLog zerolog.Logger, address string, vlan *Network) (*ApplicationNode, error) {
-	a := &ApplicationNode{
-		log: localLog,
-	}
-
-	// build a name, save the address
-	a.name = fmt.Sprintf("app @ %s", address)
-	var err error
-	a.address, err = NewAddress(NA(address))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating address")
-	}
-
-	// build a local device object
-	localDevice := &TestDeviceObject{
-		LocalDeviceObject: &LocalDeviceObject{
-			ObjectName:       a.name,
-			ObjectIdentifier: "device:999",
-			VendorIdentifier: 999,
-		},
-	}
-
-	// continue with initialization
-	a.Application, err = NewApplication(localLog, WithApplicationLocalDeviceObject(localDevice.LocalDeviceObject)) //TODO: this is a indirection that wasn't intended... we don't use the annotation yet so that might be fine
-	if err != nil {
-		return nil, errors.Wrap(err, "error building application")
-	}
-
-	a.WhoIsIAmServices, err = NewWhoIsIAmServices(localLog, a, WithWhoIsIAmServicesLocalDevice(localDevice.LocalDeviceObject)) //TODO: this is a indirection that wasn't intended... we don't use the annotation yet so that might be fine
-	if err != nil {
-		return nil, errors.Wrap(err, "error building WhoIsIAmServices")
-	}
-
-	// include a application decoder
-	a.asap, err = NewApplicationServiceAccessPoint(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error building application service access point")
-	}
-
-	// pass the device object to the state machine access point so it
-	// can know if it should support segmentation
-	// the segmentation state machines need access to the same device
-	// information cache as the application
-	a.smap, err = NewStateMachineAccessPoint(localLog, localDevice.LocalDeviceObject, WithStateMachineAccessPointDeviceInfoCache(a.GetDeviceInfoCache())) //TODO: this is a indirection that wasn't intended... we don't use the annotation yet so that might be fine
-	if err != nil {
-		return nil, errors.Wrap(err, "error building state machine access point")
-	}
-
-	// a network service access point will be needed
-	a.nsap, err = NewNetworkServiceAccessPoint(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service access point")
-	}
-
-	// give the NSAP a generic network layer service element
-	a.nse, err = new_NetworkServiceElement(localLog)
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating network service element")
-	}
-	err = Bind(localLog, a.nse, a.nsap)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	// bind the top layers
-	err = Bind(localLog, a, a.asap, a.smap, a.nsap)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-
-	// create a node, added to the network
-	a.node, err = NewNode(a.log, a.address, WithNodeLan(vlan))
-	if err != nil {
-		return nil, errors.Wrap(err, "error creating node")
-	}
-
-	// bind the stack to the local network
-	err = a.nsap.Bind(a.node, nil, nil)
-	if err != nil {
-		return nil, errors.Wrap(err, "error binding")
-	}
-	if !LogTestNetwork {
-		a.log = zerolog.Nop()
-	}
-	return a, nil
-}
-
 func xtob(s string) []byte {
 	bytes, err := Xtob(s)
 	if err != nil {
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationLayerStateMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationLayerStateMachine.go
new file mode 100644
index 0000000..ff15caa
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationLayerStateMachine.go
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/appservice"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/tests/state_machine"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
+)
+
+//go:generate plc4xGenerator -type=ApplicationLayerStateMachine -prefix=helpers_
+type ApplicationLayerStateMachine struct {
+	ApplicationServiceElementContract
+	*ClientStateMachine `ignore:"true"` // TODO: add support
+
+	name    string
+	address *Address
+
+	asap *ApplicationServiceAccessPoint
+	smap *StateMachineAccessPoint
+	nsap *NetworkServiceAccessPoint
+	nse  *_NetworkServiceElement
+	node *Node
+
+	log zerolog.Logger
+}
+
+func NewApplicationLayerStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*ApplicationLayerStateMachine, error) {
+	a := &ApplicationLayerStateMachine{
+		log: localLog,
+	}
+
+	// save the name and address
+	a.name = fmt.Sprintf("app @ %s", address)
+	var err error
+	a.address, err = NewAddress(NA(address))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creaing address")
+	}
+
+	// build a local device object
+	localDevice := TestDeviceObject{
+		NewLocalDeviceObject(NoArgs,
+			NKW(KWObjectName, a.name,
+				KWObjectIdentifier, "device:"+address,
+				KWVendorIdentifier, 999,
+			)),
+	}
+
+	if LogTestNetwork {
+		a.log.Debug().Stringer("address", a.address).Msg("address")
+	}
+
+	// continue with initialization
+	a.ApplicationServiceElementContract, err = NewApplicationServiceElement(a.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating application service")
+	}
+	a.ClientStateMachine, err = NewClientStateMachine(a.log, WithClientStateMachineName(localDevice.GetObjectName()), WithClientStateMachineExtension(a))
+	if err != nil {
+		return nil, errors.Wrap(err, "error building client state machine")
+	}
+
+	// include a application decoder
+	a.asap, err = NewApplicationServiceAccessPoint(a.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating application service access point")
+	}
+
+	// pass the device object to the state machine access point so it
+	// can know if it should support segmentation
+	a.smap, err = NewStateMachineAccessPoint(a.log, localDevice)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating state machine access point")
+	}
+
+	// the segmentation state machines need access to some device
+	// information cache, usually shared with the application
+	a.smap.SetDeviceInfoCache(NewDeviceInfoCache(a.log))
+
+	//  a network service access point will be needed
+	a.nsap, err = NewNetworkServiceAccessPoint(a.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service access point")
+	}
+
+	//  give the NSAP a generic network layer service element
+	a.nse, err = new_NetworkServiceElement(a.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service element")
+	}
+	err = Bind(a.log, a.nse, a.nsap)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	//  bind the top layers
+	err = Bind(a.log, a, a.asap, a.smap, a.nsap)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	//  create a node, added to the network
+	a.node, err = NewNode(a.log, a.address, WithNodeLan(vlan))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating node")
+	}
+	if LogTestNetwork {
+		a.log.Debug().Stringer("node", a.node).Msg("node")
+	}
+
+	//  bind the stack to the local network
+	err = a.nsap.Bind(a.node, nil, nil)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	if !LogTestNetwork {
+		a.log = zerolog.Nop()
+	}
+	return a, nil
+}
+
+func (a *ApplicationLayerStateMachine) Indication(args Args, kwArgs KWArgs) error {
+	a.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
+	return a.Receive(args, NoKWArgs())
+}
+
+func (a *ApplicationLayerStateMachine) Confirmation(args Args, kwArgs KWArgs) error {
+	a.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Confirmation")
+	return a.Receive(args, NoKWArgs())
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationNode.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationNode.go
new file mode 100644
index 0000000..35a611c
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_ApplicationNode.go
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/app"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/appservice"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/service"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
+)
+
+//go:generate plc4xGenerator -type=ApplicationNode -prefix=helpers_
+type ApplicationNode struct {
+	*Application
+	*WhoIsIAmServices
+	*ReadWritePropertyServices
+	*DefaultRFormatter `ignore:"true"`
+
+	name    string
+	address *Address `directSerialize:"true"`
+	asap    *ApplicationServiceAccessPoint
+	smap    *StateMachineAccessPoint
+	nsap    *NetworkServiceAccessPoint
+	nse     *_NetworkServiceElement
+	node    *Node
+
+	log zerolog.Logger
+}
+
+func NewApplicationNode(localLog zerolog.Logger, address string, vlan *Network) (*ApplicationNode, error) {
+	a := &ApplicationNode{
+		DefaultRFormatter: NewDefaultRFormatter(),
+		log:               localLog,
+	}
+
+	// build a name, save the address
+	a.name = fmt.Sprintf("app @ %s", address)
+	var err error
+	a.address, err = NewAddress(NA(address))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating address")
+	}
+
+	// build a local device object
+	localDevice := &TestDeviceObject{
+		LocalDeviceObject: NewLocalDeviceObject(NoArgs,
+			NKW(
+				KWObjectName, a.name,
+				KWObjectIdentifier, "device:999",
+				KWVendorIdentifier, 999,
+			),
+		),
+	}
+
+	// continue with initialization
+	a.Application, err = NewApplication(localLog, WithApplicationLocalDeviceObject(localDevice))
+	if err != nil {
+		return nil, errors.Wrap(err, "error building application")
+	}
+
+	a.WhoIsIAmServices, err = NewWhoIsIAmServices(localLog, a, WithWhoIsIAmServicesLocalDevice(localDevice))
+	if err != nil {
+		return nil, errors.Wrap(err, "error building WhoIsIAmServices")
+	}
+
+	// include a application decoder
+	a.asap, err = NewApplicationServiceAccessPoint(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error building application service access point")
+	}
+
+	// pass the device object to the state machine access point so it
+	// can know if it should support segmentation
+	// the segmentation state machines need access to the same device
+	// information cache as the application
+	a.smap, err = NewStateMachineAccessPoint(localLog, localDevice.LocalDeviceObject, WithStateMachineAccessPointDeviceInfoCache(a.GetDeviceInfoCache())) //TODO: this is a indirection that wasn't intended... we don't use the annotation yet so that might be fine
+	if err != nil {
+		return nil, errors.Wrap(err, "error building state machine access point")
+	}
+
+	// a network service access point will be needed
+	a.nsap, err = NewNetworkServiceAccessPoint(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service access point")
+	}
+
+	// give the NSAP a generic network layer service element
+	a.nse, err = new_NetworkServiceElement(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service element")
+	}
+	err = Bind(localLog, a.nse, a.nsap)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	// bind the top layers
+	err = Bind(localLog, a, a.asap, a.smap, a.nsap)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	// create a node, added to the network
+	a.node, err = NewNode(a.log, a.address, WithNodeLan(vlan))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating node")
+	}
+
+	// bind the stack to the local network
+	err = a.nsap.Bind(a.node, nil, nil)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+	if !LogTestNetwork {
+		a.log = zerolog.Nop()
+	}
+	return a, nil
+}
+
+func (a *ApplicationNode) AlternateString() (string, bool) {
+	if IsDebuggingActive() {
+		return fmt.Sprintf("%s", a), true
+	}
+	return "", false
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NPDUCodec.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NPDUCodec.go
new file mode 100644
index 0000000..fa45ecc
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NPDUCodec.go
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/npdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+)
+
+//go:generate plc4xGenerator -type=NPDUCodec -prefix=helpers_
+type NPDUCodec struct {
+	ClientContract
+	ServerContract
+
+	log zerolog.Logger
+}
+
+func NewNPDUCodec(localLog zerolog.Logger) (*NPDUCodec, error) {
+	n := &NPDUCodec{
+		log: localLog,
+	}
+	var err error
+	n.ClientContract, err = NewClient(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating client")
+	}
+	n.ServerContract, err = NewServer(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating client")
+	}
+	if !LogTestNetwork {
+		n.log = zerolog.Nop()
+	}
+	return n, nil
+}
+
+func (n *NPDUCodec) Indication(args Args, kwArgs KWArgs) error {
+	n.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
+
+	npdu := GA[NPDU](args, 0)
+
+	// first a generic _NPDU
+	xpdu, err := NewNPDU(Nothing())
+	if err != nil {
+		return errors.Wrap(err, "error creating NPDU")
+	}
+	if err := npdu.Encode(xpdu); err != nil {
+		return errors.Wrap(err, "error encoding xpdu")
+	}
+
+	// Now as a vanilla PDU
+	ypdu := NewPDU(Nothing())
+	if err := xpdu.Encode(ypdu); err != nil {
+		return errors.Wrap(err, "error decoding xpdu")
+	}
+	n.log.Debug().Stringer("ypdu", ypdu).Msg("encoded")
+
+	// send it downstream
+	return n.Request(NA(ypdu), NoKWArgs())
+}
+
+func (n *NPDUCodec) Confirmation(args Args, kwArgs KWArgs) error {
+	n.log.Debug().Stringer("Args", args).Stringer("KWArgs", kwArgs).Msg("Indication")
+
+	pdu := GA[PDU](args, 0)
+
+	// decode as generic _NPDU
+	xpdu, err := NewNPDU(Nothing())
+	if err != nil {
+		return errors.Wrap(err, "error creating NPDU")
+	}
+	if err := xpdu.Decode(pdu); err != nil {
+		return errors.Wrap(err, "error decoding xpdu")
+	}
+
+	// drop application layer message
+	if xpdu.GetNPDUNetMessage() == nil {
+		n.log.Trace().Msg("drop message")
+		return nil
+	}
+
+	// do a deeper decode of the _NPDU
+	ypdu := NPDUTypes[*xpdu.GetNPDUNetMessage()]()
+	if err := ypdu.Decode(xpdu); err != nil {
+		return errors.Wrap(err, "error decoding ypdu")
+	}
+
+	return n.Response(NA(ypdu), NoKWArgs())
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NetworkLayerStateMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NetworkLayerStateMachine.go
new file mode 100644
index 0000000..87b002b
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_NetworkLayerStateMachine.go
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/tests/state_machine"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
+)
+
+type NetworkLayerStateMachine struct {
+	*ClientStateMachine
+
+	address *Address
+
+	log   zerolog.Logger
+	codec *NPDUCodec
+	node  *Node
+}
+
+func NewNetworkLayerStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*NetworkLayerStateMachine, error) {
+	n := &NetworkLayerStateMachine{
+		log: localLog,
+	}
+	var err error
+	n.ClientStateMachine, err = NewClientStateMachine(localLog, WithClientStateMachineName(address), WithClientStateMachineExtension(n))
+	if err != nil {
+		return nil, errors.Wrap(err, "error building client state machine")
+	}
+
+	// save the name and address
+	n.address, err = NewAddress(NA(address))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creaing address")
+	}
+
+	// create a network layer encoder/decoder
+	n.codec, err = NewNPDUCodec(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating codec")
+	}
+	if LogTestNetwork {
+		n.log.Debug().Stringer("codec", n.codec).Msg("codec")
+	}
+
+	// create a node, added to the network
+	n.node, err = NewNode(localLog, n.address, WithNodeLan(vlan))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating node")
+	}
+	if LogTestNetwork {
+		n.log.Debug().Stringer("node", n.node).Msg("node")
+	}
+
+	// bind this to the node
+	if err := Bind(localLog, n, n.codec, n.node); err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+	if !LogTestNetwork {
+		n.log = zerolog.Nop()
+	}
+	return n, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterNode.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterNode.go
new file mode 100644
index 0000000..e756f83
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterNode.go
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
+)
+
+type RouterNode struct {
+	nsap *NetworkServiceAccessPoint
+	nse  *_NetworkServiceElement
+
+	log zerolog.Logger
+}
+
+func NewRouterNode(localLog zerolog.Logger) (*RouterNode, error) {
+	r := &RouterNode{log: localLog}
+	var err error
+	// a network service access point will be needed
+	r.nsap, err = NewNetworkServiceAccessPoint(r.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service access point")
+	}
+	// give the NSAP a generic network layer service element
+	r.nse, err = new_NetworkServiceElement(r.log)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service element")
+	}
+	err = Bind(r.log, r.nse, r.nsap)
+	if err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+	if !LogTestNetwork {
+		r.log = zerolog.Nop()
+	}
+	return r, nil
+}
+
+func (r *RouterNode) AddNetwork(address string, vlan *Network, net uint16) error {
+	r.log.Debug().Str("address", address).Stringer("vlan", vlan).Uint16("net", net).Msg("AddNetwork")
+
+	// convert the address to an Address
+	addr, err := NewAddress(NA(address))
+	if err != nil {
+		return errors.Wrap(err, "error creaing address")
+	}
+
+	// create a node, add to the network
+	node, err := NewNode(r.log, addr, WithNodeLan(vlan))
+	if err != nil {
+		return errors.Wrap(err, "error creating node")
+	}
+
+	// bind the BIP stack to the local network
+	return r.nsap.Bind(node, &net, addr)
+}
+
+func (r *RouterNode) String() string {
+	return fmt.Sprintf("RouterNode")
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterStaterMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterStaterMachine.go
new file mode 100644
index 0000000..27ddc43
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_RouterStaterMachine.go
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/tests/state_machine"
+)
+
+type RouterStateMachine struct {
+	*RouterNode
+	StateMachineContract
+}
+
+func NewRouterStateMachine(localLog zerolog.Logger) (*RouterStateMachine, error) {
+	r := &RouterStateMachine{}
+	var err error
+	r.RouterNode, err = NewRouterNode(localLog)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating router node")
+	}
+	var initFunc func()
+	r.StateMachineContract, initFunc = NewStateMachine(localLog, r)
+	initFunc()
+	if !LogTestNetwork {
+		r.log = zerolog.Nop()
+	}
+	return r, nil
+}
+
+func (r *RouterStateMachine) Send(args Args, kwArgs KWArgs) error {
+	panic("not available")
+}
+
+func (r *RouterStateMachine) String() string {
+	return "RouterStateMachine"
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_SnifferStateMachine.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_SnifferStateMachine.go
new file mode 100644
index 0000000..d4760d2
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_SnifferStateMachine.go
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/pdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/tests/state_machine"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/vlan"
+)
+
+type SnifferStateMachine struct {
+	*ClientStateMachine
+
+	address *Address
+	node    *Node
+
+	log zerolog.Logger
+}
+
+func NewSnifferStateMachine(localLog zerolog.Logger, address string, vlan *Network) (*SnifferStateMachine, error) {
+	s := &SnifferStateMachine{
+		log: localLog,
+	}
+	var err error
+	s.ClientStateMachine, err = NewClientStateMachine(s.log, WithClientStateMachineName(address), WithClientStateMachineExtension(s))
+	if err != nil {
+		return nil, errors.Wrap(err, "error building client state machine")
+	}
+
+	// save the name and address
+	s.address, err = NewAddress(NA(address))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating address")
+	}
+
+	// create a promiscuous node, added to the network
+	s.node, err = NewNode(s.log, s.address, WithNodePromiscuous(true), WithNodeLan(vlan))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating node")
+	}
+	if LogTestNetwork {
+		s.log.Debug().Stringer("node", s.node).Msg("node")
+	}
+
+	// bind the stack together
+	if err := Bind(s.log, s, s.node); err != nil {
+		return nil, errors.Wrap(err, "error binding")
+	}
+
+	if !LogTestNetwork {
+		s.log = zerolog.Nop()
+	}
+	return s, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_TestDeviceObject.go
similarity index 65%
copy from plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
copy to plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_TestDeviceObject.go
index efbea52..693e903 100644
--- a/plc4go/internal/bacnetip/bacgopes/object/object_ReadWritePropertyServices.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers_TestDeviceObject.go
@@ -17,19 +17,10 @@
  * under the License.
  */
 
-package object
+package test_network
 
-import . "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comp"
+import "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/local/device"
 
-//go:generate plc4xGenerator -type=ReadWritePropertyServices -prefix=object_
-type ReadWritePropertyServices struct {
-}
-
-func NewReadWritePropertyServices() (*ReadWritePropertyServices, error) {
-	// TODO: implement me
-	return nil, nil
-}
-
-func (*ReadWritePropertyServices) Confirmation(Args, KWArgs) error {
-	panic("implement me")
+type TestDeviceObject struct {
+	device.LocalDeviceObject
 }
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers__NetworkServiceElement.go b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers__NetworkServiceElement.go
new file mode 100644
index 0000000..4ba1adb
--- /dev/null
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_network/helpers__NetworkServiceElement.go
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package test_network
+
+import (
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/debugging"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/netservice"
+)
+
+type _NetworkServiceElement struct {
+	*NetworkServiceElement
+	*DefaultRFormatter
+}
+
+func new_NetworkServiceElement(localLog zerolog.Logger) (*_NetworkServiceElement, error) {
+	i := &_NetworkServiceElement{
+		DefaultRFormatter: NewDefaultRFormatter(),
+	}
+
+	// This class turns off the deferred startup function call that broadcasts
+	// I-Am-Router-To-Network and Network-Number-Is messages.
+	var err error
+	i.NetworkServiceElement, err = NewNetworkServiceElement(localLog, WithNetworkServiceElementStartupDisabled(true))
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating network service element")
+	}
+	return i, nil
+}
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_segmentation/test_1_test.go b/plc4go/internal/bacnetip/bacgopes/tests/test_segmentation/test_1_test.go
index 548363f..e42eeb5 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_segmentation/test_1_test.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_segmentation/test_1_test.go
@@ -28,7 +28,7 @@
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/apdu"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/apdu"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/app"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/appservice"
 	. "github.com/apache/plc4x/plc4go/internal/bacnetip/bacgopes/comm"
@@ -75,7 +75,7 @@
 	log zerolog.Logger
 }
 
-func NewApplicationNetwork(localLog zerolog.Logger, tdDeviceObject, iutDeviceObject *LocalDeviceObject) (*ApplicationNetwork, error) {
+func NewApplicationNetwork(localLog zerolog.Logger, tdDeviceObject, iutDeviceObject LocalDeviceObject) (*ApplicationNetwork, error) {
 	a := &ApplicationNetwork{
 		log: localLog,
 	}
@@ -247,7 +247,7 @@
 	log zerolog.Logger
 }
 
-func NewApplicationStateMachine(localLog zerolog.Logger, localDevice *LocalDeviceObject, vlan *Network, opts ...func(*ApplicationStateMachine)) (*ApplicationStateMachine, error) {
+func NewApplicationStateMachine(localLog zerolog.Logger, localDevice LocalDeviceObject, vlan *Network, opts ...func(*ApplicationStateMachine)) (*ApplicationStateMachine, error) {
 	a := &ApplicationStateMachine{
 		log: localLog,
 	}
@@ -255,7 +255,7 @@
 		opt(a)
 	}
 	// build and address and save it
-	_, instance := ObjectIdentifierStringToTuple(localDevice.ObjectIdentifier)
+	_, instance := ObjectIdentifierStringToTuple(localDevice.GetObjectIdentifier())
 	var err error
 	a.address, err = NewAddress(NA(instance))
 	if err != nil {
@@ -269,7 +269,7 @@
 		return nil, errors.Wrap(err, "error creating application io controller")
 	}
 	var init func()
-	a.StateMachineContract, init = NewStateMachine(a.log, a, WithStateMachineName(localDevice.ObjectName))
+	a.StateMachineContract, init = NewStateMachine(a.log, a, WithStateMachineName(localDevice.GetObjectName()))
 	init()
 
 	// include a application decoder
@@ -367,25 +367,31 @@
 	octets206 := model.MaxApduLengthAccepted_NUM_OCTETS_206
 	segmentation := model.BACnetSegmentation_SEGMENTED_BOTH
 	maxSegmentsAccepted := model.MaxSegmentsAccepted_NUM_SEGMENTS_04
-	tdDeviceObject := &LocalDeviceObject{
-		ObjectName:                "td",
-		ObjectIdentifier:          "device:10",
-		MaximumApduLengthAccepted: &octets206,
-		SegmentationSupported:     &segmentation,
-		MaxSegmentsAccepted:       &maxSegmentsAccepted,
-		VendorIdentifier:          999,
-	}
+	tdDeviceObject := NewLocalDeviceObject(
+		NoArgs,
+		NKW(
+			KWObjectName, "td",
+			KWObjectIdentifier, "device:10",
+			KWMaximumApduLengthAccepted, &octets206,
+			KWSegmentationSupported, &segmentation,
+			KWMaxSegmentsAccepted, &maxSegmentsAccepted,
+			KWVendorIdentifier, 999,
+		),
+	)
 
 	// server device object
 	maxSegmentsAccepted = model.MaxSegmentsAccepted_NUM_SEGMENTS_64
-	iutDeviceObject := &LocalDeviceObject{
-		ObjectName:                "td",
-		ObjectIdentifier:          "device:10",
-		MaximumApduLengthAccepted: &octets206,
-		SegmentationSupported:     &segmentation,
-		MaxSegmentsAccepted:       &maxSegmentsAccepted,
-		VendorIdentifier:          999,
-	}
+	iutDeviceObject := NewLocalDeviceObject(
+		NoArgs,
+		NKW(
+			KWObjectName, "td",
+			KWObjectIdentifier, "device:10",
+			KWMaximumApduLengthAccepted, &octets206,
+			KWSegmentationSupported, &segmentation,
+			KWMaxSegmentsAccepted, &maxSegmentsAccepted,
+			KWVendorIdentifier, 999,
+		),
+	)
 
 	// create a network
 	anet, err := NewApplicationNetwork(testingLogger, tdDeviceObject, iutDeviceObject)
@@ -433,7 +439,7 @@
 			KnownKey("serviceParameters"), requestString,
 			KnownKey("destination"), anet.iut.address,
 		)), nil).Doc(prefix+"-1").
-		Receive(NA((*apdu.ConfirmedPrivateTransferRequest)(nil)), NoKWArgs()).Doc(prefix + "-2").
+		Receive(NA((*ConfirmedPrivateTransferRequest)(nil)), NoKWArgs()).Doc(prefix + "-2").
 		Success("")
 
 	// no IUT application layer matching
diff --git a/plc4go/internal/bacnetip/bacgopes/tests/test_service/helpers.go b/plc4go/internal/bacnetip/bacgopes/tests/test_service/helpers.go
index 756cfa0..b991fa5 100644
--- a/plc4go/internal/bacnetip/bacgopes/tests/test_service/helpers.go
+++ b/plc4go/internal/bacnetip/bacgopes/tests/test_service/helpers.go
@@ -63,9 +63,9 @@
 
 	trafficLog      *TrafficLog
 	vlan            *Network
-	tdDeviceObject  *LocalDeviceObject
+	tdDeviceObject  LocalDeviceObject
 	td              *ApplicationStateMachine
-	iutDeviceObject *LocalDeviceObject
+	iutDeviceObject LocalDeviceObject
 	iut             *ApplicationStateMachine
 
 	log zerolog.Logger
@@ -89,13 +89,16 @@
 	// test device object
 	octets1024 := model.MaxApduLengthAccepted_NUM_OCTETS_1024
 	segmentation := model.BACnetSegmentation_NO_SEGMENTATION
-	a.tdDeviceObject = &LocalDeviceObject{
-		ObjectName:                "td",
-		ObjectIdentifier:          "device:10",
-		MaximumApduLengthAccepted: &octets1024,
-		SegmentationSupported:     &segmentation,
-		VendorIdentifier:          999,
-	}
+	a.tdDeviceObject = NewLocalDeviceObject(
+		NoArgs,
+		NKW(
+			KWObjectName, "td",
+			KWObjectIdentifier, "device:10",
+			KWMaximumApduLengthAccepted, &octets1024,
+			KWSegmentationSupported, &segmentation,
+			KWVendorIdentifier, 999,
+		),
+	)
 
 	// test device
 	var err error
@@ -108,13 +111,16 @@
 	// implementation under test device object
 	octets1024 = model.MaxApduLengthAccepted_NUM_OCTETS_1024
 	segmentation = model.BACnetSegmentation_NO_SEGMENTATION
-	a.iutDeviceObject = &LocalDeviceObject{
-		ObjectName:                "iut",
-		ObjectIdentifier:          "device:20",
-		MaximumApduLengthAccepted: &octets1024,
-		SegmentationSupported:     &segmentation,
-		VendorIdentifier:          999,
-	}
+	a.iutDeviceObject = NewLocalDeviceObject(
+		NoArgs,
+		NKW(
+			KWObjectName, "iut",
+			KWObjectIdentifier, "device:20",
+			KWMaximumApduLengthAccepted, &octets1024,
+			KWSegmentationSupported, &segmentation,
+			KWVendorIdentifier, 999,
+		),
+	)
 
 	// implementation under test
 	a.iut, err = NewApplicationStateMachine(localLog, a.iutDeviceObject, a.vlan)
@@ -352,13 +358,13 @@
 	log zerolog.Logger
 }
 
-func NewApplicationStateMachine(localLog zerolog.Logger, localDevice *LocalDeviceObject, vlan *Network) (*ApplicationStateMachine, error) {
+func NewApplicationStateMachine(localLog zerolog.Logger, localDevice LocalDeviceObject, vlan *Network) (*ApplicationStateMachine, error) {
 	a := &ApplicationStateMachine{
 		log: localLog,
 	}
 
 	// build and address and save it
-	_, instance := ObjectIdentifierStringToTuple(localDevice.ObjectIdentifier)
+	_, instance := ObjectIdentifierStringToTuple(localDevice.GetObjectIdentifier())
 	var err error
 	a.address, err = NewAddress(NA(instance))
 	if err != nil {
@@ -372,7 +378,7 @@
 		return nil, errors.Wrap(err, "error creating application io controller")
 	}
 	var init func()
-	a.StateMachineContract, init = NewStateMachine(a.log, a, WithStateMachineName(localDevice.ObjectName))
+	a.StateMachineContract, init = NewStateMachine(a.log, a, WithStateMachineName(localDevice.GetObjectName()))
 	init()
 
 	// include a application decoder
diff --git a/plc4go/internal/bacnetip/bacgopes/udp/udp_UDPDirector.go b/plc4go/internal/bacnetip/bacgopes/udp/udp_UDPDirector.go
index 693efed..9bf6d34 100644
--- a/plc4go/internal/bacnetip/bacgopes/udp/udp_UDPDirector.go
+++ b/plc4go/internal/bacnetip/bacgopes/udp/udp_UDPDirector.go
@@ -232,7 +232,7 @@
 		d.handleError(errors.Wrap(err, "error parsing destination address"))
 		return
 	}
-	pdu := NewCPDU(readBytes, NKW(KWCompRootMessage, bvlc, KWCPCISource, saddr, KWCPCIDestination, daddr)) // TODO: why do we set the destination here??? This might be completely wrong
+	pdu := NewCPDU(readBytes, NKW(KWCPCISource, saddr, KWCPCIDestination, daddr), WithRootMessage(bvlc)) // TODO: why do we set the destination here??? This might be completely wrong
 	// send the _PDU up to the client
 	d.wg.Add(1)
 	go func() {