Follow up on FELIX-3621
The runtime must also adapts its method id computation.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1387917 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
index 063ae2b..eb2e9eb 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
@@ -23,6 +23,7 @@
 
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.metadata.Element;
+import org.objectweb.asm.Type;
 
 /**
  * A Method Metadata represents a method from the implementation class.
@@ -99,13 +100,16 @@
         StringBuffer identifier = new StringBuffer(m_name);
         for (int i = 0; i < m_arguments.length; i++) {
             String arg = m_arguments[i];
-            identifier.append('$');
             if (arg.endsWith("[]")) {
-                arg = arg.substring(0, arg.length() - 2);
-                identifier.append(arg.replace('.', '_'));
-                identifier.append("__"); // Replace [] by __
+                // We have to replace all []
+                String acc = "";
+                while (arg.endsWith("[]")) {
+                    arg = arg.substring(0, arg.length() - 2);
+                    acc += "__";
+                }
+                identifier.append("$" + arg.replace('.', '_') + acc);
             } else {
-                identifier.append(arg.replace('.', '_'));
+                identifier.append("$" + arg.replace('.', '_'));
             }
         }
         return identifier.toString();
@@ -122,14 +126,27 @@
         for (int i = 0; i < args.length; i++) {
             identifier.append('$'); // Argument separator.
             if (args[i].isArray()) {
+                String acc = "__";
                 if (args[i].getComponentType().isPrimitive()) {
                     // Primitive array
                     identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else if (args[i].getComponentType().isArray()) {
+                    // Multi-directional array.
+                    Class current = args[i].getComponentType();
+                    while (current.isArray()) {
+                        acc += "__";
+                        current = current.getComponentType();
+                    }
+                    if (current.isPrimitive()) {
+                        acc = FieldMetadata.getPrimitiveTypeByClass(current) + acc;
+                    } else {
+                        acc = current.getName().replace('.', '_') + acc;
+                    }
                 } else {
                     // Object array
                     identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
                 }
-                identifier.append("__"); // Add __ (array)
+                identifier.append(acc); // Add __ (array)
             } else {
                 if (args[i].isPrimitive()) {
                     // Primitive type
@@ -160,14 +177,22 @@
 
             identifier.append('$'); // Argument separator.
             if (args[i].isArray()) {
+                String acc = "__";
                 if (args[i].getComponentType().isPrimitive()) {
                     // Primitive array
                     identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else if (args[i].getComponentType().isArray()) {
+                    // Multi-directional array.
+                    Class current = args[i].getComponentType();
+                    while (current.isArray()) {
+                        acc += "__";
+                        current = current.getComponentType();
+                    }
                 } else {
                     // Object array
                     identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
                 }
-                identifier.append("__"); // Add __ (array)
+                identifier.append(acc); // Add __ (array)
             } else {
                 if (args[i].isPrimitive()) {
                     // Primitive type
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java
new file mode 100644
index 0000000..203f1d9
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/MethodMetadataTest.java
@@ -0,0 +1,109 @@
+package org.apache.felix.ipojo.parser;
+
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.lang.reflect.Method;
+
+public class MethodMetadataTest extends TestCase {
+
+    public void testIdComputationForArrays() throws NoSuchMethodException {
+        Method method = this.getClass().getMethod("withOneArray", new String[0].getClass());
+        String id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withOneArray$java_lang_String__", id);
+
+        method = this.getClass().getMethod("withDoubleArray", new String[0][0].getClass());
+        id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withDoubleArray$java_lang_String____", id);
+
+        method = this.getClass().getMethod("withTripleArray", new String[0][0][0].getClass());
+        id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withTripleArray$java_lang_String______", id);
+    }
+
+    public void testIdComputationForArraysUsingPrimitive() throws NoSuchMethodException {
+        Method method = this.getClass().getMethod("withPrimitiveArray", new int[0].getClass());
+        String id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withPrimitiveArray$int__", id);
+
+        method = this.getClass().getMethod("withPrimitiveArray", new int[0][0].getClass());
+        id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withPrimitiveArray$int____", id);
+
+        method = this.getClass().getMethod("withPrimitiveArray", new int[0][0][0].getClass());
+        id = MethodMetadata.computeMethodId(method);
+        Assert.assertEquals("withPrimitiveArray$int______", id);
+    }
+
+    public void testComputationForArraysUsingObjectsFromElement() {
+        Element metadata1 = new Element("method", null);
+        metadata1.addAttribute(new Attribute("name", "withOneArray"));
+        metadata1.addAttribute(new Attribute("arguments", "{java.lang.String[]}"));
+
+        Element metadata2 = new Element("method", null);
+        metadata2.addAttribute(new Attribute("name", "withOneArray"));
+        metadata2.addAttribute(new Attribute("arguments", "{java.lang.String[][]}"));
+
+        Element metadata3 = new Element("method", null);
+        metadata3.addAttribute(new Attribute("name", "withOneArray"));
+        metadata3.addAttribute(new Attribute("arguments", "{java.lang.String[][][]}"));
+
+        MethodMetadata methodMetadata1 = new MethodMetadata(metadata1);
+        Assert.assertEquals("withOneArray$java_lang_String__", methodMetadata1.getMethodIdentifier());
+
+        MethodMetadata methodMetadata2 = new MethodMetadata(metadata2);
+        Assert.assertEquals("withOneArray$java_lang_String____", methodMetadata2.getMethodIdentifier());
+
+        MethodMetadata methodMetadata3 = new MethodMetadata(metadata3);
+        Assert.assertEquals("withOneArray$java_lang_String______", methodMetadata3.getMethodIdentifier());
+    }
+
+    public void testComputationForArraysUsingPrimitiveFromElement() {
+        Element metadata1 = new Element("method", null);
+        metadata1.addAttribute(new Attribute("name", "withOneArray"));
+        metadata1.addAttribute(new Attribute("arguments", "{int[]}"));
+
+        Element metadata2 = new Element("method", null);
+        metadata2.addAttribute(new Attribute("name", "withOneArray"));
+        metadata2.addAttribute(new Attribute("arguments", "{int[][]}"));
+
+        Element metadata3 = new Element("method", null);
+        metadata3.addAttribute(new Attribute("name", "withOneArray"));
+        metadata3.addAttribute(new Attribute("arguments", "{int[][][]}"));
+
+        MethodMetadata methodMetadata1 = new MethodMetadata(metadata1);
+        Assert.assertEquals("withOneArray$int__", methodMetadata1.getMethodIdentifier());
+
+        MethodMetadata methodMetadata2 = new MethodMetadata(metadata2);
+        Assert.assertEquals("withOneArray$int____", methodMetadata2.getMethodIdentifier());
+
+        MethodMetadata methodMetadata3 = new MethodMetadata(metadata3);
+        Assert.assertEquals("withOneArray$int______", methodMetadata3.getMethodIdentifier());
+    }
+
+
+    // Method analyzed for testing
+
+    public void withOneArray(String[] arr) { }
+    public void withPrimitiveArray(int[] arr) { }
+    public void withDoubleArray(String[][] arr) { }
+    public void withPrimitiveArray(int[][] arr) { }
+    public void withPrimitiveArray(int[][][] arr) { }
+    public void withTripleArray(String[][][] arr) { }
+
+    public MethodMetadataTest() {
+        super();
+    }
+
+    // Constructor used for testing
+    public MethodMetadataTest(String[] arr) { }
+    public MethodMetadataTest(String[][] arr) { }
+    public MethodMetadataTest(int[] arr) { }
+    public MethodMetadataTest(int[][] arr) { }
+    public MethodMetadataTest(int[][][] arr) { }
+
+
+}