/*
 *  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 java.security.cert;

/**
 * The interface specification for determining whether a CRL meets some criteria
 * to select CRL objects among a set of {@code CRL}s.
 * <p>
 * The implementations of this interface are typically used to define the
 * criteria for selecting {@code CRL}s from a {@code CertStore}.
 * </p>
 * 
 * @see CertStore
 * @see CRL
 * @since Android 1.0
 */
public interface CRLSelector extends Cloneable {

    /**
     * Clones this {@code CRLSelector} instance.
     * 
     * @return the cloned instance.
     * @since Android 1.0
     */
    public Object clone();

    /**
     * Checks whether the defined criteria of this instance match the specified
     * CRL.
     * 
     * @param crl
     *            the CRL to be evaluated.
     * @return {@code true} if the CRL matches the criteria, {@code false}
     *         otherwise.
     * @since Android 1.0
     */
    public boolean match(CRL crl);
}