/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.functor.core.collection;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;

import org.apache.commons.functor.UnaryFunction;

/**
 * Returns the size of the specified Collection, or the length
 * of the specified array or String.
 *
 * @param <A> the function argument type.
 * @version $Revision$ $Date$
 * @author Rodney Waldhoff
 */
public final class Size<A> implements UnaryFunction<A, Integer>, Serializable {

    /**
     * serialVersionUID declaration.
     */
    private static final long serialVersionUID = -12374650738412129L;
    /**
     * A static {@code Size} instance reference.
     */
    private static final Size<Object> INSTANCE = new Size<Object>();

    // constructor
    // ------------------------------------------------------------------------
    /**
     * Create a new Size.
     */
    public Size() { }

    /**
     * {@inheritDoc}
     */
    public Integer evaluate(Object obj) {
        if (obj instanceof Collection<?>) {
            return evaluate((Collection<?>) obj);
        }
        if (obj instanceof String) {
            return evaluate((String) obj);
        }
        if (null != obj && obj.getClass().isArray()) {
            return evaluateArray(obj);
        }
        if (null == obj) {
            throw new IllegalArgumentException("Argument must not be null");
        }
        throw new IllegalArgumentException("Expected Collection, String or Array, found " + obj);
    }

    /**
     * {@inheritDoc}
     */
    public boolean equals(Object that) {
        return that instanceof Size<?>;
    }

    /**
     * {@inheritDoc}
     */
    public int hashCode() {
        return "Size".hashCode();
    }

    /**
     * {@inheritDoc}
     */
    public String toString() {
        return "Size()";
    }

    /**
     * Get a Size instance.
     * @return Size
     */
    public static Size<Object> instance() {
        return INSTANCE;
    }

    /**
     * Evaluate a Collection.
     * @param col to evaluate
     * @return Integer
     */
    private int evaluate(Collection<?> col) {
        return col.size();
    }

    /**
     * Evaluate a String.
     * @param str to evaluate
     * @return Integer
     */
    private int evaluate(String str) {
        return str.length();
    }

    /**
     * Evaluate an array.
     * @param array to evaluate
     * @return Integer
     */
    private int evaluateArray(Object array) {
        return Array.getLength(array);
    }

}

@@ -2873,35 +2873,39 @@
  */%0A    private 
-i
+I
 nt
+eger
  evaluate(Collec
@@ -2934,16 +2934,32 @@
  return 
+Integer.valueOf(
 col.size
@@ -2960,16 +2960,17 @@
 l.size()
+)
 ;%0A    %7D%0A
@@ -3069,35 +3069,39 @@
  */%0A    private 
-i
+I
 nt
+eger
  evaluate(String
@@ -3123,16 +3123,32 @@
  return 
+Integer.valueOf(
 str.leng
@@ -3151,16 +3151,17 @@
 length()
+)
 ;%0A    %7D%0A
@@ -3270,19 +3270,23 @@
 private 
-i
+I
 nt
+eger
  evaluat
@@ -3323,16 +3323,32 @@
  return 
+Integer.valueOf(
 Array.ge
@@ -3361,16 +3361,17 @@
 h(array)
+)
 ;%0A    %7D%0A

Make return type agree with Javadoc and avoid boxing warnings