Description: Provide a default implementation of the abstract Structure.getFieldOrder()
 method to preserve the compatibility with JNA < 3.5.0. The implementation is derived
 from the JNA 3.4.2 code.
Author: Emmanuel Bourg <ebourg@apache.org>
Forwarded: not-needed
--- a/src/com/sun/jna/Structure.java
+++ b/src/com/sun/jna/Structure.java
@@ -106,6 +106,34 @@
      */
     public interface ByReference { }
 
+    private static class MemberOrder {
+        private static final String[] FIELDS = { "first", "second", "middle", "penultimate", "last" };
+        public int first;
+        public int second;
+        public int middle;
+        public int penultimate;
+        public int last;
+    }
+
+    private static final boolean REVERSE_FIELDS;
+    private static final boolean REQUIRES_FIELD_ORDER;
+
+    static {
+        // Check for predictable field order; IBM and JRockit store fields in
+        // reverse order; Excelsior JET requires explicit order
+        Field[] fields = MemberOrder.class.getFields();
+        List names = new ArrayList();
+        for (int i=0; i < fields.length; i++) {
+            names.add(fields[i].getName());
+        }
+        List expected = Arrays.asList(MemberOrder.FIELDS);
+        List reversed = new ArrayList(expected);
+        Collections.reverse(reversed);
+
+        REVERSE_FIELDS = names.equals(reversed);
+        REQUIRES_FIELD_ORDER = !(names.equals(expected) || REVERSE_FIELDS);
+    }
+
     /** Use the platform default alignment. */
     public static final int ALIGN_DEFAULT = 0;
     /** No alignment, place all fields on nearest 1-byte boundary */
@@ -831,7 +859,32 @@
      * field order as returned by {@link Class#getFields()} is not
      * guaranteed to be predictable.
      */
-    protected abstract List getFieldOrder();
+    protected List getFieldOrder() {
+        if (REQUIRES_FIELD_ORDER) {
+            throw new Error("This VM does not store fields in a predictable order; you must implement Structure.getFieldOrder on " + getClass() + " to explicitly indicate the field order: " + System.getProperty("java.vendor") + ", " + System.getProperty("java.version"));
+        }
+
+        return getFieldNames();
+    }
+
+    private List<String> getFieldNames() {
+        List<String> names = new ArrayList<String>();
+        for (Class cls = getClass(); !cls.equals(Structure.class); cls = cls.getSuperclass()) {
+            List<String> fields = new ArrayList<String>();
+            for (Field field : cls.getDeclaredFields()) {
+                int modifiers = field.getModifiers();
+                if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
+                    continue;
+                }
+                fields.add(field.getName());
+            }
+            if (REVERSE_FIELDS) {
+                Collections.reverse(fields);
+            }
+            names.addAll(0, fields);
+        }
+        return names;
+    }
 
     /**
      * Force a compile-time error on the old method of field definition
