/*
 * Copyright 2018 the original author or authors.
 *
 * 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.gradle.api.provider;

import javax.annotation.Nullable;
import java.util.Map;
import java.util.Set;

/**
 * Represents a property whose type is a {@link Map} of keys of type {@link K} and values of type {@link V}. Retains iteration order.
 *
 * <p>
 * You can create a {@link MapProperty} instance using factory method {@link org.gradle.api.model.ObjectFactory#mapProperty(Class, Class)}.
 * </p>
 *
 * <p><b>Note:</b> This interface is not intended for implementation by build script or plugin authors.
 *
 * @param <K> the type of keys.
 * @param <V> the type of values.
 */
public interface MapProperty<K, V> extends Provider<Map<K, V>> {

    /**
     * Sets the value of this property to an empty map, and replaces any existing value.
     *
     * @return this property.
     */
    MapProperty<K, V> empty();

    /**
     * Returns a provider that resolves to the value of the mapping of the given key. It will have no value
     * if the property has no value, or if it does not contain a mapping for the key.
     *
     * <p>The returned provider will track the value of this property and query its value when it is queried.</p>
     *
     * <p>This method is equivalent to
     *
     * <pre><code>
     *     map(m -&gt; m.get(key))
     * </code></pre>
     *
     * but possibly more efficient.
     *
     * @param key the key
     * @return a {@link Provider} for the value
     */
    Provider<V> getting(K key);

    /**
     * Sets the value of this property to the entries of the given Map, and replaces any existing value.
     * This property will query the entries of the map each time the value of this property is queried.
     *
     * <p>This method can also be used to clear the value of the property, by passing {@code null} as the value.
     *
     * @param entries the entries, can be {@code null}
     */
    void set(@Nullable Map<? extends K, ? extends V> entries);

    /**
     * Sets the property to have the same value of the given provider, and replaces any existing value.
     *
     * This property will track the value of the provider and query its value each time the value of this property is queried.
     * When the provider has no value, this property will also have no value.
     *
     * @param provider Provider of the entries.
     */
    void set(Provider<? extends Map<? extends K, ? extends V>> provider);

    /**
     * Adds a map entry to the property value.
     *
     * @param key the key
     * @param value the value
     */
    void put(K key, V value);

    /**
     * Adds a map entry to the property value.
     *
     * <p>The given provider will be queried when the value of this property is queried.
     * This property will have no value when the given provider has no value.
     *
     * @param key the key
     * @param providerOfValue the provider of the value
     */
    void put(K key, Provider<? extends V> providerOfValue);

    /**
     * Adds all entries from another {@link Map} to the property value.
     *
     * @param entries a {@link Map} containing the entries to add
     */
    void putAll(Map<? extends K, ? extends V> entries);

    /**
     * Adds all entries from another {@link Map} to the property value.
     *
     * <p>The given provider will be queried when the value of this property is queried.
     * This property will have no value when the given provider has no value.
     *
     * @param provider the provider of the entries
     */
    void putAll(Provider<? extends Map<? extends K, ? extends V>> provider);

    /**
     * Returns a {@link Provider} that returns the set of keys for the map that is the property value.
     *
     * <p>The returned provider will track the value of this property and query its value when it is queried.</p>
     *
     * <p>This method is equivalent to
     *
     * <pre><code>
     *     map(m -&gt; m.keySet())
     * </code></pre>
     *
     * but possibly more efficient.
     *
     * @return a {@link Provider} that provides the set of keys for the map
     */
    Provider<Set<K>> keySet();

    /**
     * Disallows further changes to the value of this property. Calls to methods that change the value of this property, such as {@link #set(Map)} or {@link #put(K, V)} will fail.
     *
     * <p>When this property has elements provided by a {@link Provider}, the value of the provider is queried when this method is called  and the value of the provider will no longer be tracked.</p>
     *
     * <p>Note that although the value of the property will not change, the resulting collection may contain mutable objects. Calling this method does not guarantee that the value will become immutable.</p>
     */
    void finalizeValue();
}

@@ -4844,20 +4844,30 @@
 nk #put(
-K, V
+Object, Object
 )%7D will 

fix method reference in Javadoc