/*
 * Copyright (C) 2008 TranceCode Software
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 *
 * $Id$
 */
package org.trancecode.lang;

import org.trancecode.api.Nullable;

/**
 * @author Herve Quiroz
 */
public final class TcObjects
{
    private TcObjects()
    {
        // No instantiation
    }

    public static int hashCode(@Nullable final Object object)
    {
        if (object == null)
        {
            return 0;
        }

        return object.hashCode();
    }

    public static int hashCode(final Object... objects)
    {
        if (objects.length == 0)
        {
            throw new IllegalArgumentException();
        }

        int hashCode = hashCode(objects[0]);
        for (int i = 1; i < objects.length; i++)
        {
            hashCode <<= 4;
            hashCode ^= hashCode(objects[i]);
        }

        return hashCode;
    }

    public static boolean equals(@Nullable final Object object1, @Nullable final Object object2)
    {
        if (object1 == object2)
        {
            return true;
        }

        if (object1 != null)
        {
            return object1.equals(object2);
        }

        return false;
    }

    public static boolean pairEquals(final Object... objects)
    {
        if (objects.length % 2 != 0)
        {
            throw new IllegalArgumentException("size = " + objects.length);
        }

        for (int i = 0; i < objects.length; i += 2)
        {
            if (!equals(objects[i], objects[i + 1]))
            {
                return false;
            }
        }

        return true;
    }

    public static <T> T conditional(final boolean condition, final T ifTrue, final T ifFalse)
    {
        if (condition)
        {
            return ifTrue;
        }
        else
        {
            return ifFalse;
        }
    }
}

@@ -833,35 +833,164 @@
 ort 
-org.trancecode.api.Nullable
+com.google.common.base.Preconditions;%0Aimport com.google.common.base.Supplier;%0Aimport org.trancecode.api.Nullable;%0Aimport org.trancecode.function.TcSuppliers
 ;%0A%0A/
@@ -2637,11 +2637,754 @@
  %7D%0A    %7D
+%0A%0A    public static Supplier%3CInteger%3E immutableObjectHashCode(final Object... properties)%0A    %7B%0A        Preconditions.checkNotNull(properties);%0A%0A        return TcSuppliers.memoize(new Supplier%3CInteger%3E()%0A        %7B%0A            @Override%0A            public Integer get()%0A            %7B%0A                return TcObjects.hashCode(properties);%0A            %7D%0A        %7D);%0A    %7D%0A%0A    public static Supplier%3CString%3E immutableObjectToString(final String format, final Object... args)%0A    %7B%0A        Preconditions.checkNotNull(format);%0A%0A        return TcSuppliers.memoize(new Supplier%3CString%3E()%0A        %7B%0A            @Override%0A            public String get()%0A            %7B%0A                return String.format(format, args);%0A            %7D%0A        %7D);%0A    %7D
 %0A%7D%0A

Add two new methods to ease memoization of hashCode() and toString() method result for immutable objects