diff --git a/src/objects/zcl_abapgit_object_asfc.clas.abap b/src/objects/zcl_abapgit_object_asfc.clas.abap
new file mode 100644
index 000000000..374865f0f
--- /dev/null
+++ b/src/objects/zcl_abapgit_object_asfc.clas.abap
@@ -0,0 +1,109 @@
+CLASS zcl_abapgit_object_asfc DEFINITION
+ PUBLIC
+ INHERITING FROM zcl_abapgit_objects_super
+ CREATE PUBLIC .
+
+ PUBLIC SECTION.
+
+ INTERFACES zif_abapgit_object .
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+
+CLASS ZCL_ABAPGIT_OBJECT_ASFC IMPLEMENTATION.
+
+
+ METHOD zif_abapgit_object~changed_by.
+ rv_user = zcl_abapgit_objects_super=>c_user_unknown.
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~compare_to_remote_version.
+ CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~delete.
+
+ DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
+
+ CREATE OBJECT lo_generic
+ EXPORTING
+ is_item = ms_item.
+
+ lo_generic->delete( ).
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~deserialize.
+
+ DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
+
+ CREATE OBJECT lo_generic
+ EXPORTING
+ is_item = ms_item.
+
+ lo_generic->deserialize(
+ iv_package = iv_package
+ io_xml = io_xml ).
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~exists.
+
+ DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
+
+ CREATE OBJECT lo_generic
+ EXPORTING
+ is_item = ms_item.
+
+ rv_bool = lo_generic->exists( ).
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~get_metadata.
+
+ rs_metadata = get_metadata( ).
+ rs_metadata-delete_tadir = abap_true.
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~has_changed_since.
+
+ rv_changed = abap_true.
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~is_locked.
+
+ rv_is_locked = abap_false.
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~jump.
+
+ zcx_abapgit_exception=>raise( |TODO: Jump| ).
+
+ ENDMETHOD.
+
+
+ METHOD zif_abapgit_object~serialize.
+
+ DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
+
+ CREATE OBJECT lo_generic
+ EXPORTING
+ is_item = ms_item.
+
+ lo_generic->serialize( io_xml ).
+
+ ENDMETHOD.
+ENDCLASS.
diff --git a/src/objects/zcl_abapgit_object_asfc.clas.xml b/src/objects/zcl_abapgit_object_asfc.clas.xml
new file mode 100644
index 000000000..1d15f2e46
--- /dev/null
+++ b/src/objects/zcl_abapgit_object_asfc.clas.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ ZCL_ABAPGIT_OBJECT_ASFC
+ 1
+ E
+ ASFC
+ 2
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/objects/zcl_abapgit_objects_generic.clas.abap b/src/objects/zcl_abapgit_objects_generic.clas.abap
new file mode 100644
index 000000000..9f09da2ff
--- /dev/null
+++ b/src/objects/zcl_abapgit_objects_generic.clas.abap
@@ -0,0 +1,682 @@
+CLASS zcl_abapgit_objects_generic DEFINITION
+ PUBLIC
+ CREATE PUBLIC .
+
+ PUBLIC SECTION.
+
+ METHODS constructor
+ IMPORTING
+ !is_item TYPE zif_abapgit_definitions=>ty_item
+ RAISING
+ zcx_abapgit_exception .
+ METHODS delete
+ RAISING
+ zcx_abapgit_exception .
+ METHODS deserialize
+ IMPORTING
+ !iv_package TYPE devclass
+ !io_xml TYPE REF TO zcl_abapgit_xml_input
+ RAISING
+ zcx_abapgit_exception .
+ METHODS exists
+ RETURNING
+ VALUE(rv_bool) TYPE abap_bool
+ RAISING
+ zcx_abapgit_exception .
+ METHODS serialize
+ IMPORTING
+ !io_xml TYPE REF TO zcl_abapgit_xml_output
+ RAISING
+ zcx_abapgit_exception .
+ PROTECTED SECTION.
+
+ TYPES:
+ BEGIN OF ty_s_objkey,
+ num TYPE numc3,
+ value TYPE char128,
+ END OF ty_s_objkey .
+ TYPES:
+ ty_t_objkey TYPE SORTED TABLE OF ty_s_objkey WITH UNIQUE KEY num .
+
+ DATA ms_object_header TYPE objh .
+ DATA:
+ mt_object_table TYPE STANDARD TABLE OF objsl WITH DEFAULT KEY .
+ DATA:
+ mt_object_method TYPE STANDARD TABLE OF objm WITH DEFAULT KEY .
+ DATA ms_item TYPE zif_abapgit_definitions=>ty_item .
+
+ METHODS after_import .
+ METHODS before_export .
+ METHODS corr_insert
+ IMPORTING
+ !iv_package TYPE devclass
+ RAISING
+ zcx_abapgit_exception .
+ METHODS deserialize_data
+ IMPORTING
+ !io_xml TYPE REF TO zcl_abapgit_xml_input
+ RAISING
+ zcx_abapgit_exception .
+ METHODS distribute_name_to_components
+ IMPORTING
+ !it_key_component TYPE ddfields
+ CHANGING
+ !ct_objkey TYPE ty_t_objkey
+ !cs_objkey TYPE ty_s_objkey
+ !cv_non_value_pos TYPE numc3 .
+ METHODS get_key_fields
+ IMPORTING
+ !iv_table TYPE objsl-tobj_name
+ RETURNING
+ VALUE(rt_keys) TYPE ddfields
+ RAISING
+ zcx_abapgit_exception .
+ METHODS get_primary_table
+ RETURNING
+ VALUE(rv_table) TYPE objsl-tobj_name
+ RAISING
+ zcx_abapgit_exception .
+ METHODS get_where_clause
+ IMPORTING
+ !iv_tobj_name TYPE objsl-tobj_name
+ RETURNING
+ VALUE(rv_where) TYPE string
+ RAISING
+ zcx_abapgit_exception .
+ METHODS serialize_data
+ IMPORTING
+ !io_xml TYPE REF TO zcl_abapgit_xml_output
+ RAISING
+ zcx_abapgit_exception .
+ METHODS split_value_to_keys
+ IMPORTING
+ !it_key_component TYPE ddfields
+ CHANGING
+ !ct_objkey TYPE ty_t_objkey
+ !cs_objkey TYPE ty_s_objkey
+ !cv_non_value_pos TYPE numc3 .
+ METHODS validate
+ IMPORTING
+ !io_xml TYPE REF TO zcl_abapgit_xml_input
+ RAISING
+ zcx_abapgit_exception .
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+
+CLASS ZCL_ABAPGIT_OBJECTS_GENERIC IMPLEMENTATION.
+
+
+ METHOD after_import.
+
+ DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
+ ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
+ lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY.
+
+ FIELD-SYMBOLS LIKE LINE OF mt_object_method.
+
+
+ ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr.
+ ls_cts_object_entry-object = ms_item-obj_type.
+ ls_cts_object_entry-obj_name = ms_item-obj_name.
+ INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.
+
+ READ TABLE mt_object_method ASSIGNING
+ WITH KEY
+ objectname = ms_item-obj_type
+ objecttype = 'L'
+ method = 'AFTER_IMP'.
+ IF sy-subrc = 0.
+* client is actually optional for most AIM, but let's supply it and hope
+* that those client-independent-ones just ignore it
+ CALL FUNCTION -methodname
+ EXPORTING
+ iv_tarclient = sy-mandt
+ iv_is_upgrade = abap_false
+ TABLES
+ tt_e071 = lt_cts_object_entry
+ tt_e071k = lt_cts_key.
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD before_export.
+
+ DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
+ ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
+ lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY,
+ lv_client TYPE trclient.
+
+ FIELD-SYMBOLS LIKE LINE OF mt_object_method.
+
+
+ READ TABLE mt_object_method ASSIGNING
+ WITH KEY
+ objectname = ms_item-obj_type
+ objecttype = 'L'
+ method = 'BEFORE_EXP' ##no_text.
+ IF sy-subrc = 0.
+ lv_client = sy-mandt.
+
+ ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr.
+ ls_cts_object_entry-object = ms_item-obj_type.
+ ls_cts_object_entry-obj_name = ms_item-obj_name.
+ INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.
+
+ CALL FUNCTION -methodname
+ EXPORTING
+ iv_client = lv_client
+ TABLES
+ tt_e071 = lt_cts_object_entry
+ tt_e071k = lt_cts_key.
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD constructor.
+
+ CONSTANTS lc_logical_transport_object TYPE c LENGTH 1 VALUE 'L'.
+
+
+ SELECT SINGLE * FROM objh INTO ms_object_header
+ WHERE objectname = is_item-obj_type
+ AND objecttype = lc_logical_transport_object.
+ IF sy-subrc <> 0.
+ zcx_abapgit_exception=>raise( 'Not found in OBJH, or not supported' ).
+ ENDIF.
+
+* object tables
+ SELECT * FROM objsl INTO CORRESPONDING FIELDS OF TABLE mt_object_table
+ WHERE objectname = is_item-obj_type
+ AND objecttype = lc_logical_transport_object
+ AND tobject = 'TABU'.
+ IF mt_object_table IS INITIAL.
+ zcx_abapgit_exception=>raise( |Obviously corrupted object-type {
+ is_item-obj_type }: No tables defined| ).
+ ENDIF.
+
+* object methods
+ SELECT * FROM objm INTO TABLE mt_object_method
+ WHERE objectname = is_item-obj_type
+ AND objecttype = lc_logical_transport_object.
+
+ ms_item = is_item.
+
+ ENDMETHOD.
+
+
+ METHOD corr_insert.
+
+* this will also insert into TADIR
+ CALL FUNCTION 'RS_CORR_INSERT'
+ EXPORTING
+ object = ms_item-obj_name
+ object_class = ms_item-obj_type
+ mode = 'I'
+ global_lock = abap_true
+ devclass = iv_package
+ master_language = sy-langu
+ EXCEPTIONS
+ cancelled = 1
+ permission_failure = 2
+ unknown_objectclass = 3
+ OTHERS = 4.
+ IF sy-subrc <> 0.
+ zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, CMPT' ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD delete.
+
+ DATA: lv_where TYPE string,
+ lv_primary TYPE objsl-tobj_name.
+
+ FIELD-SYMBOLS LIKE LINE OF mt_object_table.
+
+
+ lv_primary = get_primary_table( ).
+
+ LOOP AT mt_object_table ASSIGNING .
+ lv_where = get_where_clause( -tobj_name ).
+ ASSERT NOT lv_where IS INITIAL.
+
+ DELETE FROM (-tobj_name) WHERE (lv_where).
+
+ IF -tobj_name = lv_primary.
+ ASSERT sy-dbcnt <= 1. "Just to be on the very safe side
+ ENDIF.
+ ENDLOOP.
+
+ ENDMETHOD.
+
+
+ METHOD deserialize.
+
+ validate( io_xml ).
+
+ delete( ).
+
+ deserialize_data( io_xml ).
+
+ after_import( ).
+
+ corr_insert( iv_package ).
+
+ ENDMETHOD.
+
+
+ METHOD deserialize_data.
+
+ DATA: lr_ref TYPE REF TO data.
+
+ FIELD-SYMBOLS: TYPE STANDARD TABLE,
+ LIKE LINE OF mt_object_table.
+
+
+ LOOP AT mt_object_table ASSIGNING .
+
+ CREATE DATA lr_ref TYPE STANDARD TABLE OF (-tobj_name).
+ ASSIGN lr_ref->* TO .
+
+ io_xml->read(
+ EXPORTING
+ iv_name = -tobj_name
+ CHANGING
+ cg_data = ).
+
+ INSERT (-tobj_name) FROM TABLE .
+ IF sy-subrc <> 0.
+ zcx_abapgit_exception=>raise( |Error inserting data, {
+ -tobj_name }| ).
+ ENDIF.
+
+ ENDLOOP.
+
+ ENDMETHOD.
+
+
+ METHOD distribute_name_to_components.
+
+ DATA: lt_key_component_uncovered LIKE it_key_component,
+ ls_key_component_uncovered LIKE LINE OF lt_key_component_uncovered,
+ ls_objkey_sub LIKE cs_objkey,
+ lv_objkey_sub_pos TYPE i,
+ lv_remaining_length TYPE i,
+ lv_count_components_covered LIKE ls_objkey_sub-num.
+
+ DATA lv_len LIKE ls_key_component_uncovered-leng.
+
+
+ lt_key_component_uncovered = it_key_component.
+ ls_objkey_sub-num = cs_objkey-num.
+ lv_objkey_sub_pos = 0.
+
+* we want to fill the atribute values which are not covered by explicit key components yet
+ lv_count_components_covered = ls_objkey_sub-num - 1.
+ DO lv_count_components_covered TIMES.
+ DELETE lt_key_component_uncovered INDEX 1.
+ ENDDO.
+
+ LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered.
+ CLEAR ls_objkey_sub-value.
+
+* Some datatype used in the key might exceed the total remaining characters length (e. g. SICF)
+ TRY.
+ lv_remaining_length = strlen( |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos ) }| ).
+ CATCH cx_sy_range_out_of_bounds.
+ lv_remaining_length = 0.
+ RETURN. ">>>>>>>>>>>>>>>>>>>>>>>>>>>
+ ENDTRY.
+ IF ls_key_component_uncovered-leng <= lv_remaining_length.
+ lv_len = ls_key_component_uncovered-leng.
+ ELSE.
+ lv_len = lv_remaining_length.
+ ENDIF.
+
+ ls_objkey_sub-value = |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos len = lv_len ) }|.
+ ls_objkey_sub-num = cv_non_value_pos.
+
+ INSERT ls_objkey_sub INTO TABLE ct_objkey.
+
+ lv_objkey_sub_pos = lv_objkey_sub_pos + ls_key_component_uncovered-leng.
+ cv_non_value_pos = cv_non_value_pos + 1.
+ CLEAR ls_objkey_sub.
+
+ IF lv_objkey_sub_pos = strlen( cs_objkey-value ).
+ cs_objkey-num = cv_non_value_pos.
+ EXIT. "end splitting - all characters captured
+ ENDIF.
+ ENDLOOP.
+
+ ENDMETHOD.
+
+
+ METHOD exists.
+
+ DATA: lv_where_clause TYPE string,
+ lv_primary TYPE objsl-tobj_name,
+ lr_table_line TYPE REF TO data.
+
+ FIELD-SYMBOLS: TYPE any.
+
+
+ lv_primary = get_primary_table( ).
+
+ lv_where_clause = get_where_clause( lv_primary ).
+
+ CREATE DATA lr_table_line TYPE (lv_primary).
+ ASSIGN lr_table_line->* TO .
+
+ SELECT SINGLE * FROM (lv_primary) INTO WHERE (lv_where_clause).
+ rv_bool = boolc( sy-dbcnt > 0 ).
+
+ ENDMETHOD.
+
+
+ METHOD get_key_fields.
+
+ DATA: lv_table TYPE ddobjname.
+
+
+ lv_table = iv_table.
+
+ CALL FUNCTION 'DDIF_NAMETAB_GET'
+ EXPORTING
+ tabname = lv_table
+ TABLES
+ dfies_tab = rt_keys
+ EXCEPTIONS
+ not_found = 1
+ OTHERS = 2.
+ IF sy-subrc <> 0.
+ zcx_abapgit_exception=>raise_t100( ).
+ ENDIF.
+
+ DELETE rt_keys WHERE keyflag = abap_false.
+
+ ENDMETHOD.
+
+
+ METHOD get_primary_table.
+
+ DATA: ls_object_table LIKE LINE OF mt_object_table.
+
+
+ READ TABLE mt_object_table INTO ls_object_table WITH KEY prim_table = abap_true.
+ IF sy-subrc <> 0.
+* Fallback. For some objects, no primary table is explicitly flagged
+* The, the one with only one key field shall be chosen
+ READ TABLE mt_object_table INTO ls_object_table WITH KEY tobjkey = '/&'. "#EC CI_SUBRC
+ ENDIF.
+ IF ls_object_table IS INITIAL.
+ zcx_abapgit_exception=>raise( |Object { ms_item-obj_type } has got no defined primary table| ).
+ ENDIF.
+
+ rv_table = ls_object_table-tobj_name.
+
+ ENDMETHOD.
+
+
+ METHOD get_where_clause.
+
+ DATA: lv_objkey_pos TYPE i,
+ lv_next_objkey_pos TYPE i,
+ lv_value_pos TYPE i,
+ lv_objkey_length TYPE i,
+ lt_objkey TYPE ty_t_objkey,
+ ls_objkey LIKE LINE OF lt_objkey,
+ lv_non_value_pos TYPE numc3,
+ lt_key_fields TYPE ddfields.
+
+ DATA: lv_is_asterix TYPE abap_bool,
+ lv_where_statement TYPE string,
+ lv_key_pos TYPE i,
+ lv_value128 TYPE string.
+
+ FIELD-SYMBOLS LIKE LINE OF mt_object_table.
+
+ FIELD-SYMBOLS LIKE LINE OF lt_key_fields.
+
+
+ READ TABLE mt_object_table ASSIGNING WITH KEY tobj_name = iv_tobj_name.
+ ASSERT sy-subrc = 0.
+
+ lt_key_fields = get_key_fields( iv_tobj_name ).
+
+* analyze the object key and compose the key (table)
+ CLEAR lt_objkey.
+ CLEAR ls_objkey.
+ lv_objkey_pos = 0.
+ lv_non_value_pos = 1.
+ lv_value_pos = 0.
+ lv_objkey_length = strlen( -tobjkey ).
+
+ WHILE lv_objkey_pos <= lv_objkey_length.
+ ls_objkey-num = lv_non_value_pos.
+* command
+ IF -tobjkey+lv_objkey_pos(1) = '/'.
+ IF NOT ls_objkey-value IS INITIAL.
+* We reached the end of a key-definition.
+* this key part may address multiple fields.
+* E. g. six characters may address one boolean field and a five-digit version field.
+* Thus, we need to analyze the remaining key components which have not been covered yet.
+ split_value_to_keys(
+ EXPORTING
+ it_key_component = lt_key_fields
+ CHANGING
+ ct_objkey = lt_objkey
+ cs_objkey = ls_objkey
+ cv_non_value_pos = lv_non_value_pos ).
+ ENDIF.
+ lv_next_objkey_pos = lv_objkey_pos + 1.
+* '*' means all further key values
+ IF -tobjkey+lv_next_objkey_pos(1) = '*'.
+ ls_objkey-value = '*'.
+ INSERT ls_objkey INTO TABLE lt_objkey.
+ CLEAR ls_objkey.
+ lv_non_value_pos = lv_non_value_pos + 1.
+ lv_objkey_pos = lv_objkey_pos + 1.
+* object name
+ ELSEIF -tobjkey+lv_next_objkey_pos(1) = '&'.
+ "TODO
+ ls_objkey-value = ms_item-obj_name.
+* The object name might comprise multiple key components (e. g. WDCC)
+* This string needs to be split
+ distribute_name_to_components(
+ EXPORTING
+ it_key_component = lt_key_fields
+ CHANGING
+ ct_objkey = lt_objkey
+ cs_objkey = ls_objkey
+ cv_non_value_pos = lv_non_value_pos ).
+ CLEAR ls_objkey.
+ lv_objkey_pos = lv_objkey_pos + 1.
+* language
+ ELSEIF -tobjkey+lv_next_objkey_pos(1) = 'L'.
+ ls_objkey-value = sy-langu.
+ INSERT ls_objkey INTO TABLE lt_objkey.
+ CLEAR ls_objkey.
+ lv_non_value_pos = lv_non_value_pos + 1.
+ lv_objkey_pos = lv_objkey_pos + 1.
+* Client
+ ELSEIF -tobjkey+lv_next_objkey_pos(1) = 'C'.
+ ls_objkey-value = sy-mandt.
+ INSERT ls_objkey INTO TABLE lt_objkey.
+ CLEAR ls_objkey.
+ lv_non_value_pos = lv_non_value_pos + 1.
+ lv_objkey_pos = lv_objkey_pos + 1.
+ ENDIF.
+ lv_value_pos = 0.
+* value
+ ELSE.
+ ls_objkey-value+lv_value_pos(1) = -tobjkey+lv_objkey_pos(1).
+ lv_value_pos = lv_value_pos + 1.
+ ENDIF.
+
+ lv_objkey_pos = lv_objkey_pos + 1.
+ ENDWHILE.
+
+* Similarly to that, fixed values might be supplied in the object key which actually make up key components
+ IF NOT ls_objkey-value IS INITIAL.
+ split_value_to_keys(
+ EXPORTING
+ it_key_component = lt_key_fields
+ CHANGING
+ ct_objkey = lt_objkey
+ cs_objkey = ls_objkey
+ cv_non_value_pos = lv_non_value_pos ).
+ ENDIF.
+
+* compose the where clause
+ lv_is_asterix = abap_false.
+ lv_key_pos = 1.
+
+ LOOP AT lt_key_fields ASSIGNING .
+ READ TABLE lt_objkey INTO ls_objkey
+ WITH TABLE KEY num = lv_key_pos.
+ IF sy-subrc <> 0 OR -fieldname = 'LANGU'.
+ CLEAR ls_objkey.
+ lv_key_pos = lv_key_pos + 1.
+ CONTINUE.
+ ENDIF.
+ IF ls_objkey-value = '*'.
+ lv_is_asterix = rs_c_true.
+ ENDIF.
+ IF lv_is_asterix = rs_c_true.
+ CONTINUE.
+ ENDIF.
+ IF NOT lv_where_statement IS INITIAL.
+ CONCATENATE lv_where_statement 'AND' INTO lv_where_statement
+ SEPARATED BY space.
+ ENDIF.
+ CONCATENATE '''' ls_objkey-value '''' INTO lv_value128.
+ CONCATENATE lv_where_statement -fieldname '='
+ lv_value128 INTO lv_where_statement SEPARATED BY space.
+ lv_key_pos = lv_key_pos + 1.
+ ENDLOOP.
+
+ rv_where = condense( lv_where_statement ).
+
+ ENDMETHOD.
+
+
+ METHOD serialize.
+
+ before_export( ).
+
+ serialize_data( io_xml ).
+
+ ENDMETHOD.
+
+
+ METHOD serialize_data.
+
+ DATA: lr_ref TYPE REF TO data,
+ lv_where TYPE string.
+
+ FIELD-SYMBOLS: TYPE STANDARD TABLE,
+ LIKE LINE OF mt_object_table.
+
+
+ LOOP AT mt_object_table ASSIGNING .
+
+ CREATE DATA lr_ref TYPE STANDARD TABLE OF (-tobj_name).
+ ASSIGN lr_ref->* TO .
+
+ lv_where = get_where_clause( -tobj_name ).
+
+ SELECT * FROM (-tobj_name)
+ INTO TABLE
+ WHERE (lv_where).
+
+ io_xml->add(
+ iv_name = -tobj_name
+ ig_data = ).
+
+ ENDLOOP.
+
+ ENDMETHOD.
+
+
+ METHOD split_value_to_keys.
+
+ DATA: lt_key_component_uncovered LIKE it_key_component,
+ ls_dummy LIKE LINE OF ct_objkey,
+ ls_key_component_uncovered LIKE LINE OF lt_key_component_uncovered,
+ ls_objkey_sub LIKE cs_objkey,
+ lv_objkey_sub_pos TYPE i.
+
+
+ lt_key_component_uncovered = it_key_component.
+
+* we want to fill the atribute values which are not covered by explicit key components yet
+ LOOP AT ct_objkey INTO ls_dummy.
+ DELETE lt_key_component_uncovered INDEX 1.
+ ENDLOOP.
+
+ ls_objkey_sub-num = cs_objkey-num.
+ lv_objkey_sub_pos = 0.
+ LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered.
+ CLEAR ls_objkey_sub-value.
+ ls_objkey_sub-value = cs_objkey-value+lv_objkey_sub_pos(ls_key_component_uncovered-leng).
+ ls_objkey_sub-num = cv_non_value_pos.
+
+ INSERT ls_objkey_sub INTO TABLE ct_objkey.
+
+ lv_objkey_sub_pos = lv_objkey_sub_pos + ls_key_component_uncovered-leng.
+ cv_non_value_pos = cv_non_value_pos + 1.
+ CLEAR ls_objkey_sub.
+
+ IF lv_objkey_sub_pos = strlen( cs_objkey-value ).
+ cs_objkey-num = cv_non_value_pos.
+ EXIT. "end splitting - all characters captured
+ ENDIF.
+ ENDLOOP.
+
+ ENDMETHOD.
+
+
+ METHOD validate.
+
+ DATA: lv_where TYPE string,
+ lv_primary TYPE objsl-tobj_name,
+ lr_ref TYPE REF TO data.
+
+ FIELD-SYMBOLS: TYPE STANDARD TABLE.
+
+
+ lv_primary = get_primary_table( ).
+
+ CREATE DATA lr_ref TYPE STANDARD TABLE OF (lv_primary).
+ ASSIGN lr_ref->* TO .
+
+ io_xml->read(
+ EXPORTING
+ iv_name = lv_primary
+ CHANGING
+ cg_data = ).
+
+ IF lines( ) = 0.
+ zcx_abapgit_exception=>raise( |Primary table { lv_primary
+ } not found in imported container | ).
+ ELSEIF lines( ) <> 1.
+ zcx_abapgit_exception=>raise( |Primary table { lv_primary
+ } contains more than one instance! | ).
+ ENDIF.
+
+ lv_where = get_where_clause( lv_primary ).
+
+* validate that max one local instance was affected by the import
+ SELECT COUNT(*) FROM (lv_primary) WHERE (lv_where).
+ IF sy-dbcnt > 1.
+ zcx_abapgit_exception=>raise( |More than one instance exists locally in primary table {
+ lv_primary }| ).
+ ENDIF.
+
+ ENDMETHOD.
+ENDCLASS.
diff --git a/src/objects/zcl_abapgit_objects_generic.clas.testclasses.abap b/src/objects/zcl_abapgit_objects_generic.clas.testclasses.abap
new file mode 100644
index 000000000..32b8fbb7f
--- /dev/null
+++ b/src/objects/zcl_abapgit_objects_generic.clas.testclasses.abap
@@ -0,0 +1,41 @@
+CLASS ltcl_test DEFINITION FOR TESTING
+ DURATION SHORT
+ RISK LEVEL HARMLESS FINAL.
+
+ PRIVATE SECTION.
+ METHODS: serialize FOR TESTING RAISING zcx_abapgit_exception.
+
+ENDCLASS.
+
+
+CLASS ltcl_test IMPLEMENTATION.
+
+ METHOD serialize.
+
+ DATA: lo_cut TYPE REF TO zcl_abapgit_objects_generic,
+ lo_xml TYPE REF TO zcl_abapgit_xml_output,
+ ls_item TYPE zif_abapgit_definitions=>ty_item.
+
+* assumption: this object exists in all SAP systems
+ ls_item-obj_type = 'ASFC'.
+ ls_item-obj_name = 'SAP_AS_TEST_001'.
+
+ CREATE OBJECT lo_cut
+ EXPORTING
+ is_item = ls_item.
+
+ CREATE OBJECT lo_xml.
+
+ lo_cut->serialize( lo_xml ).
+* checks that it does not dump
+
+ ENDMETHOD.
+
+* todo, implement tests for methods:
+* DISTRIBUTE_NAME_TO_COMPONENTS
+* GET_KEY_FIELDS
+* GET_PRIMARY_TABLE
+* GET_WHERE_CLAUSE
+* SPLIT_VALUE_TO_KEYS
+
+ENDCLASS.
diff --git a/src/objects/zcl_abapgit_objects_generic.clas.xml b/src/objects/zcl_abapgit_objects_generic.clas.xml
new file mode 100644
index 000000000..ae3f63e8f
--- /dev/null
+++ b/src/objects/zcl_abapgit_objects_generic.clas.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ ZCL_ABAPGIT_OBJECTS_GENERIC
+ 1
+ E
+ Generic object helper
+ 2
+ 1
+ X
+ X
+ X
+ X
+
+
+
+