// Copyright 2014 takahashikzn
//
// 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 jp.root42.indolently;

import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Matcher;


/**
 * Extended {@link Matcher} class for indolent person.
 * It's name comes from "Sugared Matcher".
 *
 * @author takahashikzn
 */
public interface SMatcher
    extends MatcherDelegate {

    /**
     * replace matched character sequence.
     *
     * @param f replace operator
     * @return replaced string
     * @see #replaceAll(String)
     */
    default String replace(final Function<String, String> f) {
        Objects.requireNonNull(f);

        return this.replace((m, s) -> f.apply(s));
    }

    /**
     * replace matched character sequence.
     *
     * @param f replace operator
     * @return replaced string
     * @see #replaceAll(String)
     */
    default String replace(final BiFunction<SMatcher, String, String> f) {
        Objects.requireNonNull(f);

        final StringBuffer sb = new StringBuffer();

        while (this.find()) {
            this.appendReplacement(sb, f.apply(this, this.group()));
        }

        return this.appendTail(sb).toString();
    }
}

@@ -630,313 +630,1550 @@
 til.
-Objects;%0Aimport java.util.function.BiFunction;%0Aimport java.util.function.Function;%0Aimport java.util.regex.Matcher;%0A%0A%0A/**%0A * Extended %7B@link Matcher%7D class for indolent person.%0A * It's name comes from %22Sugared Matcher%22.%0A *%0A * @author takahashikzn%0A */%0Apublic interface SMatcher%0A    extends MatcherDelegate %7B
+NoSuchElementException;%0Aimport java.util.Objects;%0Aimport java.util.function.BiConsumer;%0Aimport java.util.function.BiFunction;%0Aimport java.util.function.Function;%0Aimport java.util.function.Supplier;%0Aimport java.util.regex.Matcher;%0A%0Aimport jp.root42.indolently.ref.Ref;%0A%0Aimport static jp.root42.indolently.Expressive.*;%0Aimport static jp.root42.indolently.Indolently.*;%0A%0A%0A/**%0A * Extended %7B@link Matcher%7D class for indolent person.%0A * It's name comes from %22Sugared Matcher%22.%0A *%0A * @author takahashikzn%0A */%0Apublic interface SMatcher%0A    extends MatcherDelegate, Iterable%3CString%3E %7B%0A%0A    @Override%0A    default SIter%3CString%3E iterator() %7B%0A%0A        final Ref%3CBoolean%3E found = ref(null);%0A%0A        final Supplier%3CBoolean%3E hasNext = () -%3E optional(found.val).orElse(found.val = this.find());%0A%0A        final Supplier%3CString%3E next = () -%3E ifelse( //%0A            hasNext.get(), //%0A            () -%3E prog1(() -%3E this.group(), //%0A                () -%3E found.val = null), () -%3E %7B%0A                throw new NoSuchElementException();%0A            %7D);%0A%0A        return Iterative.iterator(hasNext, next);%0A    %7D%0A%0A    /**%0A     * Consume each matched token then return %7B@code this%7D instance which %7B@link Matcher#reset() reset%7D was called after%0A     * iteration finished.%0A     *%0A     * @param f consumer%0A     * @return %7B@code this%7D instance which is reset%0A     * @see Matcher#reset()%0A     */%0A    default SMatcher each(final BiConsumer%3C? super SMatcher, String%3E f) %7B%0A%0A        this.iterator().each(x -%3E f.accept(this, x));%0A%0A        this.reset();%0A%0A        return this;%0A    %7D
 %0A%0A  
@@ -2695,16 +2695,24 @@
 unction%3C
+? super 
 SMatcher

add iterator, each