Improve handling of deeply-nested fault subcodes

soap12_builder_helper did not properly handle fault subcodes nested more
than 2 or 3 deep.  This caused parsing issues and memory leaks. The new
implementation should handle an arbitrary number of nested subcodes.
diff --git a/axiom/src/soap/soap12_builder_helper.c b/axiom/src/soap/soap12_builder_helper.c
index 179d26d..a88a738 100644
--- a/axiom/src/soap/soap12_builder_helper.c
+++ b/axiom/src/soap/soap12_builder_helper.c
@@ -603,6 +603,24 @@
                             "fault subcode null when it should not be null");
                         return AXIS2_FAILURE;
                     }
+
+                    /* Since subcodes can be nested arbitrarily deep, we can't
+                     * just take the first subcode - we need to descend until
+                     * we find the correct parent
+                     */
+                    while (sub_code &&
+                           axiom_soap_fault_sub_code_get_base_node(sub_code, env) != parent_node)
+                    {
+
+                        sub_code = axiom_soap_fault_sub_code_get_sub_code(sub_code, env);
+                    }
+                    if(!sub_code)
+                    {
+                        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+                            "found null when searching for parent subcode");
+                        return AXIS2_FAILURE;
+                    }
+
                     value = axiom_soap_fault_value_create(env);
                     if(!value)
                     {
@@ -643,6 +661,7 @@
                                 "fault code null when it should not be null");
                             return AXIS2_FAILURE;
                         }
+
                         parent_subcode = axiom_soap_fault_code_get_sub_code(fault_code, env);
                         if(!parent_subcode)
                         {
@@ -651,6 +670,22 @@
                             return AXIS2_FAILURE;
                         }
 
+                        /* Since subcodes can be nested arbitrarily deep, we can't
+                        * just take the first subcode - we need to descend until
+                        * we find the correct parent
+                        */
+                        while (parent_subcode &&
+                            axiom_soap_fault_sub_code_get_base_node(parent_subcode, env) != parent_node) {
+
+                            parent_subcode = axiom_soap_fault_sub_code_get_sub_code(parent_subcode, env);
+                        }
+                        if(!parent_subcode)
+                        {
+                            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+                                "found null when searching for parent subcode");
+                            return AXIS2_FAILURE;
+                        }
+
                         axiom_soap_fault_sub_code_set_sub_code(parent_subcode, env, subcode);
 
                         builder_helper->subcode_value_present = AXIS2_FALSE;
diff --git a/axiom/test/resources/xml/soap/test.xml b/axiom/test/resources/xml/soap/test.xml
index 3ef9a1e..f9c6434 100644
--- a/axiom/test/resources/xml/soap/test.xml
+++ b/axiom/test/resources/xml/soap/test.xml
@@ -47,6 +47,12 @@
                         <env:Value>m:MessageTimeout In Second Subcode</env:Value>
                         <env:Subcode>
                             <env:Value>m:MessageTimeout In Third Subcode</env:Value>
+                            <env:Subcode>
+                                <env:Value>m:MessageTimeout In Fourth Subcode</env:Value>
+                                <env:Subcode>
+                                    <env:Value>m:MessageTimeout In Fifth Subcode</env:Value>
+                                </env:Subcode>
+                            </env:Subcode>
                         </env:Subcode>
                     </env:Subcode>
                 </env:Subcode>