/*
 *    Copyright (c) 2008-2011 Graham Allan
 *
 *   Licensed 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.mutabilitydetector.unittesting;

import static com.google.common.collect.Iterables.transform;
import static java.util.Arrays.asList;
import static org.mutabilitydetector.locations.Dotted.CLASS_TO_DOTTED;
import static org.mutabilitydetector.locations.Dotted.dotted;
import static org.mutabilitydetector.locations.Dotted.fromClass;

import org.hamcrest.Matcher;
import org.mutabilitydetector.MutableReasonDetail;
import org.mutabilitydetector.unittesting.matchers.reasons.AllowingForSubclassing;
import org.mutabilitydetector.unittesting.matchers.reasons.AllowingNonFinalFields;
import org.mutabilitydetector.unittesting.matchers.reasons.FieldAssumptions;
import org.mutabilitydetector.unittesting.matchers.reasons.NoReasonsAllowed;
import org.mutabilitydetector.unittesting.matchers.reasons.ProvidedOtherClass;

/**
 * Provides ways to suppress false positives generated by Mutability Detector.
 * <p>
 * Regretfully, Mutability Detector may produce false positives, which cause
 * your unit tests to fail, even though your class is immutable. In order to get
 * around this fault in Mutability Detector, you can provide an "allowed reason"
 * for mutability. This is preferable to deleting the test, or marking it as
 * ignored, as it allows checking for all other violations except those you have
 * explicitly sanctioned.
 * <p>
 * All types returned from the static methods on AllowedReason are
 * implementations of Hamcrest {@link Matcher}, generic on the type
 * {@link MutableReasonDetail}.
 * <p>
 * For more information on configuring a mutability assertion, see
 * {@link MutabilityAssert}.
 * 
 * @see MutabilityAssert
 * @see MutableReasonDetail
 * 
 * @see ProvidedOtherClass
 * @see AllowingForSubclassing
 * @see AllowingNonFinalFields
 * @see FieldAssumptions
 * @see NoReasonsAllowed
 * 
 */
public final class AllowedReason {

    private AllowedReason() {
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static ProvidedOtherClass provided(String dottedClassName) {
        return ProvidedOtherClass.provided(dotted(dottedClassName));
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static ProvidedOtherClass provided(Class<?> clazz) {
        return ProvidedOtherClass.provided(fromClass(clazz));
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static ProvidedOtherClass provided(Class<?>... classes) {
        return ProvidedOtherClass.provided(transform(asList(classes), CLASS_TO_DOTTED));
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static AllowingForSubclassing allowingForSubclassing() {
        return new AllowingForSubclassing();
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static AllowingNonFinalFields allowingNonFinalFields() {
        return new AllowingNonFinalFields();
    }

    /**
     * Please see the JavaDoc listed with {@link MutabilityAssert} for an
     * introduction on using this method.
     * 
     * @see MutabilityAssert
     */
    public static NoReasonsAllowed noReasonsAllowed() {
        return NoReasonsAllowed.noReasonsAllowed();
    }

    /**
     * Allowed reasons for mutability warnings related to fields.
     * <p>
     * Several warnings raised by Mutability Detector relate to the definition, or
     * the use, of a field in a class. For example: the definition of a field may
     * include declaring that the type of the field is mutable; or the use of a
     * field may include reassigning it outwith the constructor.
     * {@link FieldAssumptions} provides several methods which allow this category
     * of reasons.
     * <p>
     * Reasons are allowed by matching the field by it's name and then
     * matching the reasons that particular field causes mutability.
     * <p>
     * Example usage:
     * 
     * <pre><code>
     * &#064;Immutable
     * public final class UsesInternalMapForCaching {
     *   private final Map<String, String> internalCache = new HashMap<String, String>();
     *   // ... constructor, and methods which mutate the map for caching
     * }
     * 
     *  // a warning will be raised because field 'internalCache' is a mutable type.
     *  assertImmutable(UsesInternalMapForCaching.class, areImmutable());
     *  
     *  // use FieldAssumptions to insist the usage is safe
     *  assertImmutable(UsesInternalMapForCaching.class, 
     *                  areImmutable(),
     *                  assumingFields("internalCache").areModifiedAsPartOfAnUnobservableCachingStrategy());
     * </code></pre>
     * <p>
     * This method is also available in Iterable$lt;String&gt; form {@link #assumingFields(Iterable))}.
     * 
     * 
     * @see MutabilityAssert
     */ 
    public static FieldAssumptions assumingFields(String firstFieldName, String... otherFieldNames) {
        return FieldAssumptions.named(firstFieldName, otherFieldNames);
    }

    /**
     * Allowed reasons for mutability warnings related to fields.
     * <p>
     * Several warnings raised by Mutability Detector relate to the definition, or
     * the use, of a field in a class. For example: the definition of a field may
     * include declaring that the type of the field is mutable; or the use of a
     * field may include reassigning it outwith the constructor.
     * {@link FieldAssumptions} provides several methods which allow this category
     * of reasons.
     * <p>
     * Reasons are allowed by matching the field by it's name and then
     * matching the reasons that particular field causes mutability.
     * <p>
     * Example usage:
     * 
     * <pre><code>
     * &#064;Immutable
     * public final class UsesInternalMapForCaching {
     *   private final Map<String, String> internalCache = new HashMap<String, String>();
     *   // ... constructor, and methods which mutate the map for caching
     * }
     * 
     *  // a warning will be raised because field 'internalCache' is a mutable type.
     *  assertImmutable(UsesInternalMapForCaching.class, areImmutable());
     *  
     *  // use FieldAssumptions to insist the usage is safe
     *  assertImmutable(UsesInternalMapForCaching.class, 
     *                  areImmutable(),
     *                  assumingFields(Arrays.asList("internalCache")).areModifiedAsPartOfAnUnobservableCachingStrategy());
     * </code></pre>
     * <p>
     * This method is also available in varargs form {@link #assumingFields(String, String...)}.
     * 
     * 
     * @see MutabilityAssert
     */ 
    public static FieldAssumptions assumingFields(Iterable<String> named) {
        return FieldAssumptions.named(named);
    }
}

@@ -4053,292 +4053,8 @@
  %7D%0A%0A
-    /**%0A     * Please see the JavaDoc listed with %7B@link MutabilityAssert%7D for an%0A     * introduction on using this method.%0A     * %0A     * @see MutabilityAssert%0A     */%0A    public static NoReasonsAllowed noReasonsAllowed() %7B%0A        return NoReasonsAllowed.noReasonsAllowed();%0A    %7D%0A%0A
     

Remove method that was never intended for end-users to need.