What am I doing:
----------------

I have a container class named `Os`, that can contains different type elements and also instances of class `Os`. When I compare this class, I want to see :

* shallow equals for elements
* deep equals for `Os` elements

I have ensured, that every single element contained in class:

* Can not be null.
* Is comparable to same type elements.
* Is immutable. Well, at least part that I'm checking.

Following is what I have at the moment. 

Example:
--------

For example, this test case will pass.

```
    Os o1 = Os.of(3, 4d, Os.of("-"));
    Os o2 = Os.of(Os.of(Character.toString('-')), 4.0, new Integer(3));

    assertEquals(o1.toString(), "[3, 4.0, [-]]");
    assertEquals(o2.toString(), "[[-], 4.0, 3]");
    assertTrue(o1.reverse().compareTo(o2) == 0);

```

Code example:
-------------

`compareTo` method:

```
@Override
public int compareTo(final Os that) {
    final int BEFORE = -1;
    final int EQUAL = 0;
    final int AFTER = 1;
    int subresult = 0;
    Comparable<?> othis;
    Comparable<?> othat;

    if (that == null)
        return AFTER;
    if (this == that)
        return EQUAL;

    subresult = ((Integer) this.o.size()).compareTo(that.o.size());
    if (subresult < 0)
        return BEFORE;
    else if (subresult > 0)
        return AFTER;

    try {
        for (int i = 0; i < this.o.size(); i++) {
            othis = this.o.get(i);
            othat = that.o.get(i);

            if (othis.getClass() == othat.getClass()) {
                if (othat instanceof Os) {
                    subresult = ((Os) othis).compareTo(((Os) othat));
                    if (subresult < 0)
                        return BEFORE;
                    else if (subresult > 0)
                        return AFTER;
                } else {
                    subresult = hackCMP(othis, othat);
                    if (subresult < 0)
                        return BEFORE;
                    else if (subresult > 0)
                        return AFTER;
                }
            } else {
                subresult = othis.getClass().getName()
                        .compareTo(othat.getClass().getName());
                if (subresult < 0)
                    return BEFORE;
                else if (subresult > 0)
                    return AFTER;
            }
        }
        return EQUAL;
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return BEFORE;
}

private static int hackCMP(Object val, Object val2)
        throws SecurityException, NoSuchMethodException,
        IllegalArgumentException, IllegalAccessException,
        InvocationTargetException {
    Method m = val.getClass().getMethod("compareTo", val.getClass());
    return (Integer) m.invoke(val, val2);
}

```

Question:
---------

I would like to refactor the code. 

For example: 

* I would prefer not using `hackCMP` method, if possible.
* Following code segment seems to repeat itself a lot. Can I replace it with something?

```
        subresult = <expression>;
        if (subresult < 0)
            return BEFORE;
        else if (subresult > 0)
            return AFTER;
        //else ...

```

What can I refactor and how to do it? 

Edit:
-----

@wolfcastle : Data is stored in `private final ImmutableList<Comparable<?>> o;`.

I'd like to mention, that every answer was useful. Following seems to work:

```
@Override
public int compareTo(final Os that) {
    Ordering<Iterable<Comparable<?>>> order = //
    Ordering.natural().<Comparable<?>> lexicographical();
    int result = -1;

    try {
        result = ComparisonChain.start()
                .compare(this.o.size(), that.o.size())
                .compare(this.o, that.o, order).result();
    } catch (Exception e) { //ignore: type mismatch
    }

    return result;
}

```