/*
 * Copyright 2009-2014 Marcelo Guimarães
 *
 * 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 tools.devnull.trugger.util.factory;

import tools.devnull.trugger.PredicateMapper;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class DefaultContext implements Context {

  private List<Entry> entries;

  public DefaultContext() {
    this.entries = new ArrayList<>();
  }

  @Override
  public PredicateMapper<Parameter, Context> use(Object object) {
    return use((parameter) -> object);
  }

  @Override
  public PredicateMapper<Parameter, Context> use(Supplier supplier) {
    return use(parameter -> supplier.get());
  }

  @Override
  public PredicateMapper<Parameter, Context> use(Function<Parameter, Object> function) {
    return (predicate) -> {
      entries.add(new Entry(function, predicate));
      return DefaultContext.this;
    };
  }

  @Override
  public Object resolve(Parameter parameter) {
    for (Entry entry : entries) {
      if (entry.predicate.test(parameter)) {
        return entry.function.apply(parameter);
      }
    }
    throw new UnresolvableValueException();
  }

  private static class Entry {

    private final Function<Parameter, Object> function;
    private final Predicate<Parameter> predicate;

    private Entry(Function<Parameter, Object> supplier,
                  Predicate<Parameter> predicate) {
      this.function = supplier;
      this.predicate = predicate;
    }

  }

}

@@ -978,16 +978,71 @@
 entries;
+%0A  private Function%3CParameter, Object%3E defaultFunction;
 %0A%0A  publ
@@ -1476,18 +1476,21 @@
 urn 
-(p
+new P
 redicate
 ) -%3E
@@ -1489,66 +1489,302 @@
 cate
-) -%3E %7B%0A      entries.add(new Entry(function, predicate));%0A
+Mapper%3CParameter, Context%3E() %7B%0A      @Override%0A      public Context when(Predicate%3CParameter%3E condition) %7B%0A        entries.add(new Entry(function, condition));%0A        return DefaultContext.this;%0A      %7D%0A%0A      @Override%0A      public Context byDefault() %7B%0A        defaultFunction = function;%0A  
     
@@ -1809,24 +1809,32 @@
 ntext.this;%0A
+      %7D%0A
     %7D;%0A  %7D%0A%0A
@@ -2019,16 +2019,16 @@
 meter);%0A
-
       %7D%0A
@@ -2029,24 +2029,112 @@
     %7D%0A    %7D%0A
+    if (defaultFunction != null) %7B%0A      return defaultFunction.apply(parameter);%0A    %7D%0A
     throw ne

Add a default option for predicate mapper