You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/23 13:54:39 UTC

(axis-axis2-c-core) 08/10: Fix adb_XXXX_add_ functions to produce correct XML for arrays (AXIS2C-1182)

This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git

commit 478d111e28ad909ea48a5fbc6b4e5e2860e9648e
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Wed Jan 21 17:00:59 2026 -1000

    Fix adb_XXXX_add_ functions to produce correct XML for arrays (AXIS2C-1182)
    
    The add_ functions for array properties (maxOccurs > 1) were producing
    empty XML tags because the struct used a single pointer instead of an
    array list, causing values to be overwritten on each add_ call.
    
    Changes:
    - Use axutil_array_list_t* for array elements in generated structs
    - Generate add_X(), get_X_at(), sizeof_X() array accessor functions
    - Box primitive types (int, bool, double) when adding to arrays since
      axutil_array_list stores void pointers
    - Update serialization to loop through arrays creating separate XML elements
    - Update deserialization to collect repeated elements into array list
    - Properly free boxed primitives and array contents in destructor
    
    Also fixes compilation errors for nested arrays containing primitive types
    (e.g., int maxOccurs="unbounded") by boxing/unboxing values properly.
    
    Includes 8 unit tests covering array struct type, accessor functions,
    serialization, deserialization, header declarations, and destructor.
    
    Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
 tools/codegen/native/src/stub_generator.c          | 423 +++++++++++++++++----
 tools/codegen/native/test/Makefile.am              |   1 +
 .../native/test/include/adb_test_framework.h       |  27 ++
 tools/codegen/native/test/src/adb_test_framework.c |   1 +
 .../test/src/test_axis2c_1182_array_add_function.c | 316 +++++++++++++++
 5 files changed, 693 insertions(+), 75 deletions(-)

diff --git a/tools/codegen/native/src/stub_generator.c b/tools/codegen/native/src/stub_generator.c
index 874485b0d..ad34e107a 100644
--- a/tools/codegen/native/src/stub_generator.c
+++ b/tools/codegen/native/src/stub_generator.c
@@ -903,6 +903,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 const char *elem_name = elem->c_name ? elem->c_name : elem->name;
                 const char *c_type = "axis2_char_t*"; /* Default to string */
 
+                /* AXIS2C-1182: Check if this is an array element */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
                 /* AXIS2C-1421: Typeless elements are treated as anyType (axiom_node_t*) */
                 if (elem->is_typeless || elem->is_any_type) {
                     c_type = "axiom_node_t*";
@@ -925,21 +928,67 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     }
                 }
 
-                /* Getter - AXIS2C-1330: include prefix */
-                fprintf(header_file, "/**\n");
-                fprintf(header_file, " * Getter for %s\n", elem_name);
-                fprintf(header_file, " */\n");
-                fprintf(header_file, "%s AXIS2_CALL\n", c_type);
-                fprintf(header_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env);\n\n",
-                        prefix, type_name, elem_name, prefix, type_name);
-
-                /* Setter - AXIS2C-1330: include prefix */
-                fprintf(header_file, "/**\n");
-                fprintf(header_file, " * Setter for %s\n", elem_name);
-                fprintf(header_file, " */\n");
-                fprintf(header_file, "axis2_status_t AXIS2_CALL\n");
-                fprintf(header_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value);\n\n",
-                        prefix, type_name, elem_name, prefix, type_name, c_type);
+                if (is_array) {
+                    /* AXIS2C-1182: Array element - generate array-specific accessors */
+
+                    /* Getter returns the whole array list */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Getter for %s array\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "axutil_array_list_t* AXIS2_CALL\n");
+                    fprintf(header_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+
+                    /* Setter replaces the whole array list */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Setter for %s array\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(header_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, axutil_array_list_t* value);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+
+                    /* add_ function to add single item */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Add a single item to %s array\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(header_file, "%sadb_%s_add_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name, c_type);
+
+                    /* get_at function to get item at index */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Get item at index from %s array\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "%s AXIS2_CALL\n", c_type);
+                    fprintf(header_file, "%sadb_%s_get_%s_at(%sadb_%s_t* _this, const axutil_env_t *env, int index);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+
+                    /* sizeof_ function to get array size */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Get size of %s array\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "int AXIS2_CALL\n");
+                    fprintf(header_file, "%sadb_%s_sizeof_%s(%sadb_%s_t* _this, const axutil_env_t *env);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                } else {
+                    /* Non-array: standard getter/setter */
+
+                    /* Getter - AXIS2C-1330: include prefix */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Getter for %s\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "%s AXIS2_CALL\n", c_type);
+                    fprintf(header_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+
+                    /* Setter - AXIS2C-1330: include prefix */
+                    fprintf(header_file, "/**\n");
+                    fprintf(header_file, " * Setter for %s\n", elem_name);
+                    fprintf(header_file, " */\n");
+                    fprintf(header_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(header_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value);\n\n",
+                            prefix, type_name, elem_name, prefix, type_name, c_type);
+                }
             }
         }
 
@@ -1012,8 +1061,15 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 const char *elem_name = elem->c_name ? elem->c_name : elem->name;
                 const char *c_type = "axis2_char_t*";
 
+                /* AXIS2C-1182: Check if this is an array element (maxOccurs > 1 or unbounded) */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
+                if (is_array) {
+                    /* AXIS2C-1182: Array elements use axutil_array_list_t* */
+                    c_type = "axutil_array_list_t*";
+                }
                 /* AXIS2C-1421: Typeless elements are treated as anyType (axiom_node_t*) */
-                if (elem->is_typeless || elem->is_any_type) {
+                else if (elem->is_typeless || elem->is_any_type) {
                     c_type = "axiom_node_t*";
                 }
                 else if (elem->type) {
@@ -1076,8 +1132,24 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
 
                 const char *elem_name = elem->c_name ? elem->c_name : elem->name;
 
+                /* AXIS2C-1182: Check if this is an array element */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
+                if (is_array) {
+                    /* AXIS2C-1182: Free array list and its string contents */
+                    fprintf(source_file, "    if (_this->%s) {\n", elem_name);
+                    fprintf(source_file, "        int _arr_i, _arr_size = axutil_array_list_size(_this->%s, env);\n", elem_name);
+                    fprintf(source_file, "        for (_arr_i = 0; _arr_i < _arr_size; _arr_i++) {\n");
+                    fprintf(source_file, "            void *_arr_item = axutil_array_list_get(_this->%s, env, _arr_i);\n", elem_name);
+                    fprintf(source_file, "            if (_arr_item) {\n");
+                    fprintf(source_file, "                AXIS2_FREE(env->allocator, _arr_item);\n");
+                    fprintf(source_file, "            }\n");
+                    fprintf(source_file, "        }\n");
+                    fprintf(source_file, "        axutil_array_list_free(_this->%s, env);\n", elem_name);
+                    fprintf(source_file, "    }\n");
+                }
                 /* Determine how to free this property based on type */
-                if (elem->type && strstr(elem->type, "base64Binary")) {
+                else if (elem->type && strstr(elem->type, "base64Binary")) {
                     /* AXIS2C-1529: Use axutil_base64_binary_free for base64Binary */
                     fprintf(source_file, "    if (_this->%s) {\n", elem_name);
                     fprintf(source_file, "        axutil_base64_binary_free(_this->%s, env);\n", elem_name);
@@ -1118,6 +1190,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 const char *c_type = "axis2_char_t*";
                 const char *default_val = "NULL";
 
+                /* AXIS2C-1182: Check if this is an array element */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
                 /* AXIS2C-1421: Typeless elements are treated as anyType (axiom_node_t*) */
                 if (elem->is_typeless || elem->is_any_type) {
                     c_type = "axiom_node_t*";
@@ -1146,25 +1221,114 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     }
                 }
 
-                /* Getter - AXIS2C-1330: include prefix */
-                fprintf(source_file, "%s AXIS2_CALL\n", c_type);
-                fprintf(source_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env)\n",
-                        prefix, type_name, elem_name, prefix, type_name);
-                fprintf(source_file, "{\n");
-                fprintf(source_file, "    AXIS2_ENV_CHECK(env, %s);\n", default_val);
-                fprintf(source_file, "    return _this ? _this->%s : %s;\n", elem_name, default_val);
-                fprintf(source_file, "}\n\n");
-
-                /* Setter - AXIS2C-1330: include prefix */
-                fprintf(source_file, "axis2_status_t AXIS2_CALL\n");
-                fprintf(source_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value)\n",
-                        prefix, type_name, elem_name, prefix, type_name, c_type);
-                fprintf(source_file, "{\n");
-                fprintf(source_file, "    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);\n");
-                fprintf(source_file, "    AXIS2_PARAM_CHECK(env->error, _this, AXIS2_FAILURE);\n");
-                fprintf(source_file, "    _this->%s = value;\n", elem_name);
-                fprintf(source_file, "    return AXIS2_SUCCESS;\n");
-                fprintf(source_file, "}\n\n");
+                if (is_array) {
+                    /* AXIS2C-1182: Generate array accessor functions */
+
+                    /* Check if this is a primitive type that needs boxing */
+                    axis2_bool_t is_primitive = (elem->type &&
+                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                         strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
+                         strstr(elem->type, "double") || strstr(elem->type, "float")));
+
+                    /* get_ returns the whole array list */
+                    fprintf(source_file, "axutil_array_list_t* AXIS2_CALL\n");
+                    fprintf(source_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env)\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, NULL);\n");
+                    fprintf(source_file, "    return _this ? _this->%s : NULL;\n", elem_name);
+                    fprintf(source_file, "}\n\n");
+
+                    /* set_ replaces the whole array list */
+                    fprintf(source_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(source_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, axutil_array_list_t* value)\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    AXIS2_PARAM_CHECK(env->error, _this, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    _this->%s = value;\n", elem_name);
+                    fprintf(source_file, "    return AXIS2_SUCCESS;\n");
+                    fprintf(source_file, "}\n\n");
+
+                    /* AXIS2C-1182: add_ adds a single item to the array */
+                    fprintf(source_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(source_file, "%sadb_%s_add_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value)\n",
+                            prefix, type_name, elem_name, prefix, type_name, c_type);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    AXIS2_PARAM_CHECK(env->error, _this, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    if (!_this->%s) {\n", elem_name);
+                    fprintf(source_file, "        _this->%s = axutil_array_list_create(env, 4);\n", elem_name);
+                    fprintf(source_file, "        if (!_this->%s) {\n", elem_name);
+                    fprintf(source_file, "            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "            return AXIS2_FAILURE;\n");
+                    fprintf(source_file, "        }\n");
+                    fprintf(source_file, "    }\n");
+
+                    if (is_primitive) {
+                        /* Box primitive types - allocate memory for the value */
+                        fprintf(source_file, "    %s *_boxed = AXIS2_MALLOC(env->allocator, sizeof(%s));\n", c_type, c_type);
+                        fprintf(source_file, "    if (!_boxed) {\n");
+                        fprintf(source_file, "        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);\n");
+                        fprintf(source_file, "        return AXIS2_FAILURE;\n");
+                        fprintf(source_file, "    }\n");
+                        fprintf(source_file, "    *_boxed = value;\n");
+                        fprintf(source_file, "    return axutil_array_list_add(_this->%s, env, _boxed);\n", elem_name);
+                    } else {
+                        /* Pointer types can be added directly */
+                        fprintf(source_file, "    return axutil_array_list_add(_this->%s, env, value);\n", elem_name);
+                    }
+                    fprintf(source_file, "}\n\n");
+
+                    /* get_at returns a single item at index */
+                    fprintf(source_file, "%s AXIS2_CALL\n", c_type);
+                    fprintf(source_file, "%sadb_%s_get_%s_at(%sadb_%s_t* _this, const axutil_env_t *env, int index)\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, %s);\n", default_val);
+                    fprintf(source_file, "    if (!_this || !_this->%s) return %s;\n", elem_name, default_val);
+
+                    if (is_primitive) {
+                        /* Unbox primitive types - dereference the pointer */
+                        fprintf(source_file, "    %s *_boxed = (%s*)axutil_array_list_get(_this->%s, env, index);\n", c_type, c_type, elem_name);
+                        fprintf(source_file, "    return _boxed ? *_boxed : %s;\n", default_val);
+                    } else {
+                        fprintf(source_file, "    return (%s)axutil_array_list_get(_this->%s, env, index);\n", c_type, elem_name);
+                    }
+                    fprintf(source_file, "}\n\n");
+
+                    /* sizeof_ returns the array size */
+                    fprintf(source_file, "int AXIS2_CALL\n");
+                    fprintf(source_file, "%sadb_%s_sizeof_%s(%sadb_%s_t* _this, const axutil_env_t *env)\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, 0);\n");
+                    fprintf(source_file, "    if (!_this || !_this->%s) return 0;\n", elem_name);
+                    fprintf(source_file, "    return axutil_array_list_size(_this->%s, env);\n", elem_name);
+                    fprintf(source_file, "}\n\n");
+                } else {
+                    /* Non-array: standard getter/setter */
+
+                    /* Getter - AXIS2C-1330: include prefix */
+                    fprintf(source_file, "%s AXIS2_CALL\n", c_type);
+                    fprintf(source_file, "%sadb_%s_get_%s(%sadb_%s_t* _this, const axutil_env_t *env)\n",
+                            prefix, type_name, elem_name, prefix, type_name);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, %s);\n", default_val);
+                    fprintf(source_file, "    return _this ? _this->%s : %s;\n", elem_name, default_val);
+                    fprintf(source_file, "}\n\n");
+
+                    /* Setter - AXIS2C-1330: include prefix */
+                    fprintf(source_file, "axis2_status_t AXIS2_CALL\n");
+                    fprintf(source_file, "%sadb_%s_set_%s(%sadb_%s_t* _this, const axutil_env_t *env, %s value)\n",
+                            prefix, type_name, elem_name, prefix, type_name, c_type);
+                    fprintf(source_file, "{\n");
+                    fprintf(source_file, "    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    AXIS2_PARAM_CHECK(env->error, _this, AXIS2_FAILURE);\n");
+                    fprintf(source_file, "    _this->%s = value;\n", elem_name);
+                    fprintf(source_file, "    return AXIS2_SUCCESS;\n");
+                    fprintf(source_file, "}\n\n");
+                }
             }
         }
 
@@ -1197,46 +1361,110 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 const char *elem_name = elem->c_name ? elem->c_name : elem->name;
                 const char *xml_name = elem->name;  /* Use original name for XML */
 
+                /* AXIS2C-1182: Check if this is an array element */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
                 fprintf(source_file, "    /* Serialize %s */\n", elem_name);
-                fprintf(source_file, "    if (_this->%s) {\n", elem_name);
-                fprintf(source_file, "        ns = axiom_namespace_create(env, \"\", NULL);\n");
-                fprintf(source_file, "        current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
-                fprintf(source_file, "        if (current_element) {\n");
-
-                /* Handle different types for serialization */
-                if (elem->type && strstr(elem->type, "base64Binary")) {
-                    /* AXIS2C-1529: Memory-safe base64Binary serialization */
-                    fprintf(source_file, "            /* AXIS2C-1529: base64Binary - get encoded value and FREE it after use */\n");
-                    fprintf(source_file, "            text_value = axutil_base64_binary_get_encoded_binary(_this->%s, env);\n", elem_name);
-                    fprintf(source_file, "            if (text_value) {\n");
-                    fprintf(source_file, "                axiom_element_set_text(current_element, env, text_value, current_node);\n");
-                    fprintf(source_file, "                /* AXIS2C-1529 FIX: Free the encoded string to prevent memory leak */\n");
-                    fprintf(source_file, "                AXIS2_FREE(env->allocator, text_value);\n");
-                    fprintf(source_file, "                text_value = NULL;\n");
-                    fprintf(source_file, "            }\n");
-                } else if (elem->type && strstr(elem->type, "dateTime")) {
-                    fprintf(source_file, "            text_value = axutil_date_time_serialize_date_time(_this->%s, env);\n", elem_name);
-                    fprintf(source_file, "            if (text_value) {\n");
-                    fprintf(source_file, "                axiom_element_set_text(current_element, env, text_value, current_node);\n");
-                    fprintf(source_file, "                AXIS2_FREE(env->allocator, text_value);\n");
-                    fprintf(source_file, "                text_value = NULL;\n");
-                    fprintf(source_file, "            }\n");
-                } else if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
-                    fprintf(source_file, "            sprintf(tmp_buf, \"%%d\", _this->%s);\n", elem_name);
-                    fprintf(source_file, "            axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
-                } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
-                    fprintf(source_file, "            axiom_element_set_text(current_element, env, _this->%s ? \"true\" : \"false\", current_node);\n", elem_name);
-                } else if (elem->type && (strstr(elem->type, "double") || strstr(elem->type, "float"))) {
-                    fprintf(source_file, "            sprintf(tmp_buf, \"%%g\", _this->%s);\n", elem_name);
-                    fprintf(source_file, "            axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
-                } else if (!elem->is_typeless && !elem->is_any_type) {
-                    /* String type */
-                    fprintf(source_file, "            axiom_element_set_text(current_element, env, _this->%s, current_node);\n", elem_name);
-                }
-                /* anyType/typeless: the axiom_node_t* should be attached as child, not as text */
 
-                fprintf(source_file, "        }\n");
-                fprintf(source_file, "    }\n\n");
+                if (is_array) {
+                    /* AXIS2C-1182: Loop through array and serialize each item */
+                    /* Check if this is a primitive type that needs unboxing */
+                    axis2_bool_t is_primitive = (elem->type &&
+                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                         strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
+                         strstr(elem->type, "double") || strstr(elem->type, "float")));
+
+                    fprintf(source_file, "    if (_this->%s) {\n", elem_name);
+                    fprintf(source_file, "        int _ser_i, _ser_size = axutil_array_list_size(_this->%s, env);\n", elem_name);
+                    fprintf(source_file, "        for (_ser_i = 0; _ser_i < _ser_size; _ser_i++) {\n");
+
+                    if (is_primitive) {
+                        /* Primitive types are boxed - need to unbox and convert to string */
+                        if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
+                            fprintf(source_file, "            int *_arr_item = (int*)axutil_array_list_get(_this->%s, env, _ser_i);\n", elem_name);
+                            fprintf(source_file, "            if (_arr_item) {\n");
+                            fprintf(source_file, "                ns = axiom_namespace_create(env, \"\", NULL);\n");
+                            fprintf(source_file, "                current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
+                            fprintf(source_file, "                if (current_element) {\n");
+                            fprintf(source_file, "                    sprintf(tmp_buf, \"%%d\", *_arr_item);\n");
+                            fprintf(source_file, "                    axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
+                            fprintf(source_file, "                }\n");
+                            fprintf(source_file, "            }\n");
+                        } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
+                            fprintf(source_file, "            axis2_bool_t *_arr_item = (axis2_bool_t*)axutil_array_list_get(_this->%s, env, _ser_i);\n", elem_name);
+                            fprintf(source_file, "            if (_arr_item) {\n");
+                            fprintf(source_file, "                ns = axiom_namespace_create(env, \"\", NULL);\n");
+                            fprintf(source_file, "                current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
+                            fprintf(source_file, "                if (current_element) {\n");
+                            fprintf(source_file, "                    axiom_element_set_text(current_element, env, *_arr_item ? \"true\" : \"false\", current_node);\n");
+                            fprintf(source_file, "                }\n");
+                            fprintf(source_file, "            }\n");
+                        } else if (elem->type && (strstr(elem->type, "double") || strstr(elem->type, "float"))) {
+                            fprintf(source_file, "            double *_arr_item = (double*)axutil_array_list_get(_this->%s, env, _ser_i);\n", elem_name);
+                            fprintf(source_file, "            if (_arr_item) {\n");
+                            fprintf(source_file, "                ns = axiom_namespace_create(env, \"\", NULL);\n");
+                            fprintf(source_file, "                current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
+                            fprintf(source_file, "                if (current_element) {\n");
+                            fprintf(source_file, "                    sprintf(tmp_buf, \"%%g\", *_arr_item);\n");
+                            fprintf(source_file, "                    axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
+                            fprintf(source_file, "                }\n");
+                            fprintf(source_file, "            }\n");
+                        }
+                    } else {
+                        /* String or pointer types - no unboxing needed */
+                        fprintf(source_file, "            axis2_char_t *_arr_item = (axis2_char_t*)axutil_array_list_get(_this->%s, env, _ser_i);\n", elem_name);
+                        fprintf(source_file, "            if (_arr_item) {\n");
+                        fprintf(source_file, "                ns = axiom_namespace_create(env, \"\", NULL);\n");
+                        fprintf(source_file, "                current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
+                        fprintf(source_file, "                if (current_element) {\n");
+                        fprintf(source_file, "                    axiom_element_set_text(current_element, env, _arr_item, current_node);\n");
+                        fprintf(source_file, "                }\n");
+                        fprintf(source_file, "            }\n");
+                    }
+                    fprintf(source_file, "        }\n");
+                    fprintf(source_file, "    }\n\n");
+                } else {
+                    /* Non-array: single element serialization */
+                    fprintf(source_file, "    if (_this->%s) {\n", elem_name);
+                    fprintf(source_file, "        ns = axiom_namespace_create(env, \"\", NULL);\n");
+                    fprintf(source_file, "        current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
+                    fprintf(source_file, "        if (current_element) {\n");
+
+                    /* Handle different types for serialization */
+                    if (elem->type && strstr(elem->type, "base64Binary")) {
+                        /* AXIS2C-1529: Memory-safe base64Binary serialization */
+                        fprintf(source_file, "            /* AXIS2C-1529: base64Binary - get encoded value and FREE it after use */\n");
+                        fprintf(source_file, "            text_value = axutil_base64_binary_get_encoded_binary(_this->%s, env);\n", elem_name);
+                        fprintf(source_file, "            if (text_value) {\n");
+                        fprintf(source_file, "                axiom_element_set_text(current_element, env, text_value, current_node);\n");
+                        fprintf(source_file, "                /* AXIS2C-1529 FIX: Free the encoded string to prevent memory leak */\n");
+                        fprintf(source_file, "                AXIS2_FREE(env->allocator, text_value);\n");
+                        fprintf(source_file, "                text_value = NULL;\n");
+                        fprintf(source_file, "            }\n");
+                    } else if (elem->type && strstr(elem->type, "dateTime")) {
+                        fprintf(source_file, "            text_value = axutil_date_time_serialize_date_time(_this->%s, env);\n", elem_name);
+                        fprintf(source_file, "            if (text_value) {\n");
+                        fprintf(source_file, "                axiom_element_set_text(current_element, env, text_value, current_node);\n");
+                        fprintf(source_file, "                AXIS2_FREE(env->allocator, text_value);\n");
+                        fprintf(source_file, "                text_value = NULL;\n");
+                        fprintf(source_file, "            }\n");
+                    } else if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
+                        fprintf(source_file, "            sprintf(tmp_buf, \"%%d\", _this->%s);\n", elem_name);
+                        fprintf(source_file, "            axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
+                    } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
+                        fprintf(source_file, "            axiom_element_set_text(current_element, env, _this->%s ? \"true\" : \"false\", current_node);\n", elem_name);
+                    } else if (elem->type && (strstr(elem->type, "double") || strstr(elem->type, "float"))) {
+                        fprintf(source_file, "            sprintf(tmp_buf, \"%%g\", _this->%s);\n", elem_name);
+                        fprintf(source_file, "            axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
+                    } else if (!elem->is_typeless && !elem->is_any_type) {
+                        /* String type */
+                        fprintf(source_file, "            axiom_element_set_text(current_element, env, _this->%s, current_node);\n", elem_name);
+                    }
+                    /* anyType/typeless: the axiom_node_t* should be attached as child, not as text */
+
+                    fprintf(source_file, "        }\n");
+                    fprintf(source_file, "    }\n\n");
+                }
             }
         }
 
@@ -1280,12 +1508,57 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 const char *elem_name = elem->c_name ? elem->c_name : elem->name;
                 const char *xml_name = elem->name;
 
+                /* AXIS2C-1182: Check if this is an array element */
+                axis2_bool_t is_array = (elem->max_occurs > 1 || elem->max_occurs == -1);
+
                 fprintf(source_file, "                %sif (axutil_strcmp(local_name, \"%s\") == 0) {\n",
                         j > 0 ? "else " : "", xml_name);
                 fprintf(source_file, "                    text_value = axiom_element_get_text(current_element, env, current_node);\n");
 
+                if (is_array) {
+                    /* AXIS2C-1182: Collect array elements into axutil_array_list_t */
+                    /* Check if this is a primitive type that needs boxing */
+                    axis2_bool_t is_primitive = (elem->type &&
+                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                         strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
+                         strstr(elem->type, "double") || strstr(elem->type, "float")));
+
+                    fprintf(source_file, "                    if (text_value) {\n");
+                    fprintf(source_file, "                        if (!obj->%s) {\n", elem_name);
+                    fprintf(source_file, "                            obj->%s = axutil_array_list_create(env, 4);\n", elem_name);
+                    fprintf(source_file, "                        }\n");
+                    fprintf(source_file, "                        if (obj->%s) {\n", elem_name);
+
+                    if (is_primitive) {
+                        /* Box primitive types when deserializing */
+                        if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
+                            fprintf(source_file, "                            int *_boxed = AXIS2_MALLOC(env->allocator, sizeof(int));\n");
+                            fprintf(source_file, "                            if (_boxed) {\n");
+                            fprintf(source_file, "                                *_boxed = atoi(text_value);\n");
+                            fprintf(source_file, "                                axutil_array_list_add(obj->%s, env, _boxed);\n", elem_name);
+                            fprintf(source_file, "                            }\n");
+                        } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
+                            fprintf(source_file, "                            axis2_bool_t *_boxed = AXIS2_MALLOC(env->allocator, sizeof(axis2_bool_t));\n");
+                            fprintf(source_file, "                            if (_boxed) {\n");
+                            fprintf(source_file, "                                *_boxed = (axutil_strcmp(text_value, \"true\") == 0 || axutil_strcmp(text_value, \"1\") == 0) ? AXIS2_TRUE : AXIS2_FALSE;\n");
+                            fprintf(source_file, "                                axutil_array_list_add(obj->%s, env, _boxed);\n", elem_name);
+                            fprintf(source_file, "                            }\n");
+                        } else if (elem->type && (strstr(elem->type, "double") || strstr(elem->type, "float"))) {
+                            fprintf(source_file, "                            double *_boxed = AXIS2_MALLOC(env->allocator, sizeof(double));\n");
+                            fprintf(source_file, "                            if (_boxed) {\n");
+                            fprintf(source_file, "                                *_boxed = atof(text_value);\n");
+                            fprintf(source_file, "                                axutil_array_list_add(obj->%s, env, _boxed);\n", elem_name);
+                            fprintf(source_file, "                            }\n");
+                        }
+                    } else {
+                        /* String types - store duplicated string */
+                        fprintf(source_file, "                            axutil_array_list_add(obj->%s, env, axutil_strdup(env, text_value));\n", elem_name);
+                    }
+                    fprintf(source_file, "                        }\n");
+                    fprintf(source_file, "                    }\n");
+                }
                 /* Handle different types for deserialization */
-                if (elem->type && strstr(elem->type, "base64Binary")) {
+                else if (elem->type && strstr(elem->type, "base64Binary")) {
                     fprintf(source_file, "                    if (text_value) {\n");
                     fprintf(source_file, "                        axutil_base64_binary_t *b64 = axutil_base64_binary_create(env);\n");
                     fprintf(source_file, "                        if (b64) {\n");
diff --git a/tools/codegen/native/test/Makefile.am b/tools/codegen/native/test/Makefile.am
index 3312f6355..1b58e8e40 100644
--- a/tools/codegen/native/test/Makefile.am
+++ b/tools/codegen/native/test/Makefile.am
@@ -42,6 +42,7 @@ adb_test_runner_SOURCES = \
     src/test_axis2c_1573_identifier_sanitization.c \
     src/test_axis2c_1529_base64_memleak.c \
     src/test_axis2c_1613_error_on_null.c \
+    src/test_axis2c_1182_array_add_function.c \
     src/axis2_stub_compat.c
 
 # Include directories
diff --git a/tools/codegen/native/test/include/adb_test_framework.h b/tools/codegen/native/test/include/adb_test_framework.h
index 70eed7ef6..bf7e30dd3 100644
--- a/tools/codegen/native/test/include/adb_test_framework.h
+++ b/tools/codegen/native/test/include/adb_test_framework.h
@@ -365,6 +365,33 @@ extern int axis2c_1529_test_count;
 extern adb_test_case_t axis2c_1613_tests[];
 extern int axis2c_1613_test_count;
 
+/* AXIS2C-1182 array add function tests - Correct Array Serialization
+ *
+ * AXIS2C-1182: adb_XXXX_add_ functions failing to produce correct XML
+ * Analysis (2026-01-21): When using adb_Predicate_add_nodes(), the generated
+ * XML produces empty <nodes/> tags instead of separate <nodes>...</nodes>
+ * elements for each item. This is because the struct was using a single
+ * pointer instead of an axutil_array_list_t*.
+ *
+ * Fix: Native generator now:
+ * - Uses axutil_array_list_t* for array elements (maxOccurs > 1)
+ * - Generates add_X() to add items to the array list
+ * - Generates get_X_at() to get item at index
+ * - Generates sizeof_X() to get array size
+ * - Serializes array by looping through list creating separate XML elements
+ * - Deserializes array by collecting repeated elements into the list
+ *
+ * Test scenarios:
+ * - Generated struct uses axutil_array_list_t* for array elements
+ * - add_ function creates and populates array list
+ * - get_at function retrieves items by index
+ * - sizeof_ function returns array size
+ * - Serialization creates multiple XML elements
+ * - Deserialization collects multiple elements into array
+ */
+extern adb_test_case_t axis2c_1182_tests[];
+extern int axis2c_1182_test_count;
+
 /* Global test statistics */
 extern adb_test_stats_t g_test_stats;
 
diff --git a/tools/codegen/native/test/src/adb_test_framework.c b/tools/codegen/native/test/src/adb_test_framework.c
index 94a22a9ff..fcdb18a9b 100644
--- a/tools/codegen/native/test/src/adb_test_framework.c
+++ b/tools/codegen/native/test/src/adb_test_framework.c
@@ -470,6 +470,7 @@ int main(int argc, char *argv[]) {
     adb_run_test_suite(axis2c_1573_tests, axis2c_1573_test_count);
     adb_run_test_suite(axis2c_1529_tests, axis2c_1529_test_count);
     adb_run_test_suite(axis2c_1613_tests, axis2c_1613_test_count);
+    adb_run_test_suite(axis2c_1182_tests, axis2c_1182_test_count);
 
     adb_test_cleanup();
 
diff --git a/tools/codegen/native/test/src/test_axis2c_1182_array_add_function.c b/tools/codegen/native/test/src/test_axis2c_1182_array_add_function.c
new file mode 100644
index 000000000..496af2f72
--- /dev/null
+++ b/tools/codegen/native/test/src/test_axis2c_1182_array_add_function.c
@@ -0,0 +1,316 @@
+/*
+ * 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
+ *
+ *      http://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.
+ */
+
+/**
+ * AXIS2C-1182: adb_XXXX_add_ functions failing to produce correct XML
+ *
+ * Analysis: When using adb_Predicate_add_nodes(), the generated XML produces
+ * empty <nodes/> tags instead of separate <nodes>...</nodes> elements for each
+ * item. This is because the struct was using a single pointer instead of an
+ * axutil_array_list_t*, so add_ just overwrote the value each time.
+ *
+ * Fix: The native generator now:
+ * - Uses axutil_array_list_t* for array elements (maxOccurs > 1)
+ * - Generates add_X() to add items to the array list
+ * - Generates get_X_at() to get item at index
+ * - Generates sizeof_X() to get array size
+ * - Serializes array by looping through list creating separate XML elements
+ * - Deserializes array by collecting repeated elements into the list
+ *
+ * Test scenarios:
+ * - Generated struct uses axutil_array_list_t* for array elements
+ * - add_ function creates and populates array list
+ * - get_at function retrieves items by index
+ * - sizeof_ function returns array size
+ * - Serialization creates multiple XML elements
+ * - Deserialization collects multiple elements into array
+ */
+
+#include "adb_test_framework.h"
+
+/* Test 1: Verify generated struct uses axutil_array_list_t* for arrays */
+adb_test_result_t test_axis2c_1182_array_struct_type(void) {
+    printf("Testing AXIS2C-1182: Generated struct uses axutil_array_list_t* for arrays...\n");
+
+    adb_codegen_test_t test_config = {
+        .wsdl_path = "wsdl/axis2c_1182_test.wsdl",
+        .output_dir = "output/axis2c_1182_test",
+        .databinding = "adb",
+        .unwrap = 0,
+        .server_side = 0
+    };
+
+    /* WSDL with array element (maxOccurs="unbounded") */
+    const char *array_wsdl =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<definitions xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n"
+        "             xmlns:tns=\"http://axis2c.apache.org/test/\"\n"
+        "             xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
+        "             xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n"
+        "             targetNamespace=\"http://axis2c.apache.org/test/\">\n"
+        "  <types>\n"
+        "    <xsd:schema targetNamespace=\"http://axis2c.apache.org/test/\">\n"
+        "      <xsd:complexType name=\"Predicate\">\n"
+        "        <xsd:sequence>\n"
+        "          <xsd:element name=\"nodes\" type=\"xsd:string\" maxOccurs=\"unbounded\"/>\n"
+        "        </xsd:sequence>\n"
+        "      </xsd:complexType>\n"
+        "      <xsd:element name=\"PredicateRequest\" type=\"tns:Predicate\"/>\n"
+        "      <xsd:element name=\"PredicateResponse\" type=\"xsd:string\"/>\n"
+        "    </xsd:schema>\n"
+        "  </types>\n"
+        "  <message name=\"PredicateMessage\">\n"
+        "    <part name=\"body\" element=\"tns:PredicateRequest\"/>\n"
+        "  </message>\n"
+        "  <message name=\"PredicateResponseMessage\">\n"
+        "    <part name=\"body\" element=\"tns:PredicateResponse\"/>\n"
+        "  </message>\n"
+        "  <portType name=\"PredicatePortType\">\n"
+        "    <operation name=\"testPredicate\">\n"
+        "      <input message=\"tns:PredicateMessage\"/>\n"
+        "      <output message=\"tns:PredicateResponseMessage\"/>\n"
+        "    </operation>\n"
+        "  </portType>\n"
+        "  <binding name=\"PredicateBinding\" type=\"tns:PredicatePortType\">\n"
+        "    <soap:binding style=\"document\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n"
+        "    <operation name=\"testPredicate\">\n"
+        "      <soap:operation soapAction=\"urn:testPredicate\"/>\n"
+        "      <input><soap:body use=\"literal\"/></input>\n"
+        "      <output><soap:body use=\"literal\"/></output>\n"
+        "    </operation>\n"
+        "  </binding>\n"
+        "  <service name=\"PredicateService\">\n"
+        "    <port name=\"PredicatePort\" binding=\"tns:PredicateBinding\">\n"
+        "      <soap:address location=\"http://localhost:8080/axis2/services/PredicateService\"/>\n"
+        "    </port>\n"
+        "  </service>\n"
+        "</definitions>\n";
+
+    /* Create directories */
+    if (system("mkdir -p wsdl output/axis2c_1182_test") != 0) {
+        printf("Warning: Failed to create directories\n");
+    }
+
+    /* Write WSDL */
+    FILE *wsdl_file = fopen("wsdl/axis2c_1182_test.wsdl", "w");
+    ADB_ASSERT_NOT_NULL(wsdl_file, "Could not create WSDL file");
+    fputs(array_wsdl, wsdl_file);
+    fclose(wsdl_file);
+
+    /* Generate code */
+    adb_test_result_t result = adb_test_code_generation(&test_config);
+    ADB_ASSERT_TRUE(result == ADB_TEST_SUCCESS, "Code generation failed");
+
+    /* Verify generated struct uses axutil_array_list_t* */
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char line[512];
+    int found_array_list_type = 0;
+    while (fgets(line, sizeof(line), source)) {
+        /* Look for the struct definition with axutil_array_list_t* */
+        if (strstr(line, "axutil_array_list_t*") && strstr(line, "nodes")) {
+            found_array_list_type = 1;
+            break;
+        }
+    }
+    fclose(source);
+
+    ADB_ASSERT_TRUE(found_array_list_type, "Generated struct should use axutil_array_list_t* for nodes");
+
+    printf("  PASS: Generated struct uses axutil_array_list_t* for array elements\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 2: Verify add_ function is generated */
+adb_test_result_t test_axis2c_1182_add_function_generated(void) {
+    printf("Testing AXIS2C-1182: add_ function is generated...\n");
+
+    /* Uses output from previous test */
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char line[512];
+    int found_add_function = 0;
+    while (fgets(line, sizeof(line), source)) {
+        if (strstr(line, "adb_Predicate_add_nodes")) {
+            found_add_function = 1;
+            break;
+        }
+    }
+    fclose(source);
+
+    ADB_ASSERT_TRUE(found_add_function, "Generated code should have add_nodes function");
+
+    printf("  PASS: add_nodes() function is generated\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 3: Verify get_at function is generated */
+adb_test_result_t test_axis2c_1182_get_at_function_generated(void) {
+    printf("Testing AXIS2C-1182: get_at function is generated...\n");
+
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char line[512];
+    int found_get_at_function = 0;
+    while (fgets(line, sizeof(line), source)) {
+        if (strstr(line, "adb_Predicate_get_nodes_at")) {
+            found_get_at_function = 1;
+            break;
+        }
+    }
+    fclose(source);
+
+    ADB_ASSERT_TRUE(found_get_at_function, "Generated code should have get_nodes_at function");
+
+    printf("  PASS: get_nodes_at() function is generated\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 4: Verify sizeof_ function is generated */
+adb_test_result_t test_axis2c_1182_sizeof_function_generated(void) {
+    printf("Testing AXIS2C-1182: sizeof_ function is generated...\n");
+
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char line[512];
+    int found_sizeof_function = 0;
+    while (fgets(line, sizeof(line), source)) {
+        if (strstr(line, "adb_Predicate_sizeof_nodes")) {
+            found_sizeof_function = 1;
+            break;
+        }
+    }
+    fclose(source);
+
+    ADB_ASSERT_TRUE(found_sizeof_function, "Generated code should have sizeof_nodes function");
+
+    printf("  PASS: sizeof_nodes() function is generated\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 5: Verify serialization loops through array */
+adb_test_result_t test_axis2c_1182_serialization_loops(void) {
+    printf("Testing AXIS2C-1182: Serialization loops through array...\n");
+
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char buffer[32768];
+    size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, source);
+    buffer[bytes_read] = '\0';
+    fclose(source);
+
+    /* Check for serialization loop pattern */
+    int found_ser_loop = (strstr(buffer, "_ser_size = axutil_array_list_size") != NULL) &&
+                         (strstr(buffer, "for (_ser_i = 0; _ser_i < _ser_size") != NULL);
+
+    ADB_ASSERT_TRUE(found_ser_loop, "Serialization should loop through array list");
+
+    printf("  PASS: Serialization loops through array creating separate elements\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 6: Verify deserialization collects into array */
+adb_test_result_t test_axis2c_1182_deserialization_collects(void) {
+    printf("Testing AXIS2C-1182: Deserialization collects into array...\n");
+
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char buffer[32768];
+    size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, source);
+    buffer[bytes_read] = '\0';
+    fclose(source);
+
+    /* Check for deserialization array collection pattern */
+    int found_deser_collect = (strstr(buffer, "axutil_array_list_create(env, 4)") != NULL) &&
+                              (strstr(buffer, "axutil_array_list_add(obj->nodes") != NULL);
+
+    ADB_ASSERT_TRUE(found_deser_collect, "Deserialization should collect elements into array list");
+
+    printf("  PASS: Deserialization collects multiple elements into array\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 7: Verify header declarations for array functions */
+adb_test_result_t test_axis2c_1182_header_declarations(void) {
+    printf("Testing AXIS2C-1182: Header has array function declarations...\n");
+
+    FILE *header = fopen("output/axis2c_1182_test/src/adb_Predicate.h", "r");
+    ADB_ASSERT_NOT_NULL(header, "Could not open generated header file");
+
+    char buffer[16384];
+    size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, header);
+    buffer[bytes_read] = '\0';
+    fclose(header);
+
+    /* Check for function declarations */
+    int has_get = strstr(buffer, "adb_Predicate_get_nodes(") != NULL;
+    int has_set = strstr(buffer, "adb_Predicate_set_nodes(") != NULL;
+    int has_add = strstr(buffer, "adb_Predicate_add_nodes(") != NULL;
+    int has_get_at = strstr(buffer, "adb_Predicate_get_nodes_at(") != NULL;
+    int has_sizeof = strstr(buffer, "adb_Predicate_sizeof_nodes(") != NULL;
+
+    ADB_ASSERT_TRUE(has_get, "Header should declare get_nodes()");
+    ADB_ASSERT_TRUE(has_set, "Header should declare set_nodes()");
+    ADB_ASSERT_TRUE(has_add, "Header should declare add_nodes()");
+    ADB_ASSERT_TRUE(has_get_at, "Header should declare get_nodes_at()");
+    ADB_ASSERT_TRUE(has_sizeof, "Header should declare sizeof_nodes()");
+
+    printf("  PASS: Header declares all array accessor functions\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test 8: Verify destructor frees array contents */
+adb_test_result_t test_axis2c_1182_destructor_frees_array(void) {
+    printf("Testing AXIS2C-1182: Destructor properly frees array contents...\n");
+
+    FILE *source = fopen("output/axis2c_1182_test/src/adb_Predicate.c", "r");
+    ADB_ASSERT_NOT_NULL(source, "Could not open generated source file");
+
+    char buffer[32768];
+    size_t bytes_read = fread(buffer, 1, sizeof(buffer) - 1, source);
+    buffer[bytes_read] = '\0';
+    fclose(source);
+
+    /* Check for destructor array cleanup pattern */
+    int found_arr_free = (strstr(buffer, "for (_arr_i = 0; _arr_i < _arr_size") != NULL) &&
+                         (strstr(buffer, "axutil_array_list_free(") != NULL);
+
+    ADB_ASSERT_TRUE(found_arr_free, "Destructor should free array contents");
+
+    printf("  PASS: Destructor properly frees array list and contents\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test case array */
+adb_test_case_t axis2c_1182_tests[] = {
+    {"test_axis2c_1182_array_struct_type", "AXIS2C-1182: Generated struct uses axutil_array_list_t*", test_axis2c_1182_array_struct_type},
+    {"test_axis2c_1182_add_function_generated", "AXIS2C-1182: add_ function is generated", test_axis2c_1182_add_function_generated},
+    {"test_axis2c_1182_get_at_function_generated", "AXIS2C-1182: get_at function is generated", test_axis2c_1182_get_at_function_generated},
+    {"test_axis2c_1182_sizeof_function_generated", "AXIS2C-1182: sizeof_ function is generated", test_axis2c_1182_sizeof_function_generated},
+    {"test_axis2c_1182_serialization_loops", "AXIS2C-1182: Serialization loops through array", test_axis2c_1182_serialization_loops},
+    {"test_axis2c_1182_deserialization_collects", "AXIS2C-1182: Deserialization collects into array", test_axis2c_1182_deserialization_collects},
+    {"test_axis2c_1182_header_declarations", "AXIS2C-1182: Header has array function declarations", test_axis2c_1182_header_declarations},
+    {"test_axis2c_1182_destructor_frees_array", "AXIS2C-1182: Destructor properly frees array contents", test_axis2c_1182_destructor_frees_array}
+};
+
+int axis2c_1182_test_count = sizeof(axis2c_1182_tests) / sizeof(adb_test_case_t);