/**
 *
 * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved.
 *
 * 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 com.speedment.runtime.field.method;

import com.speedment.runtime.config.identifier.TableIdentifier;
import com.speedment.runtime.field.Field;

import java.util.function.Function;
import java.util.stream.Stream;

/**
 * A handle for a find-operation that can be replaced runtime to optimize a 
 * {@code Stream}. Formally, a {@code FindFrom} has the following signature:
 * {@code
 *      FK_ENTITY apply(ENTITY entity);
 * }
 * <p>
 * Each {@code FindFrom} contains metadata of which fields it compares to 
 * determine the mapping as well as a reference to the foreign manager.
 * 
 * @param <ENTITY>     the source entity
 * @param <FK_ENTITY>  the target entity
 * 
 * @author Emil Forslund
 * @since  3.0.0
 */
public interface FindFromNullable<ENTITY, FK_ENTITY> extends Function<ENTITY, Stream<FK_ENTITY>> {
    
    /**
     * Returns the field that the stream originates from. 
     * <p>
     * In the following example, {@code foo} is the source:
     * {@code
     *      foos.stream()
     *          .flatMap(foo.findBars()) // findBars returns Streamer<Foo, Bar>
     *          .forEach(...);
     * }
     * 
     * @return  the source field
     */
    Field<ENTITY> getSourceField();
    
    /**
     * Returns the field that the stream references. 
     * <p>
     * In the following example, {@code bar} is the target:
     * {@code
     *      foos.stream()
     *          .flatMap(foo.findBars()) // findBars returns Streamer<Foo, Bar>
     *          .forEach(...);
     * }
     * 
     * @return  the target field
     */
    Field<FK_ENTITY> getTargetField();
    
    /**
     * Returns the identifier for the referenced (foreign) table.
     * 
     * @return  target (foreign) table identifier
     */
    TableIdentifier<FK_ENTITY> getTableIdentifier();

}

@@ -1212,16 +1212,161 @@
 anager.%0A
+ * %3Cp%3E%0A * %7B@code FindFromNullable%7D is a specialization of %7B@link FindFrom%7D that is used%0A * to signal that the referenced entity might not exist.%0A
  * %0A * @
@@ -1487,16 +1487,17 @@
 ce  3.0.
+1
 0%0A */%0Apu
@@ -1546,17 +1546,17 @@
 _ENTITY%3E
- 
+%0A
 extends 
@@ -1592,16 +1592,209 @@
 TITY%3E%3E %7B
+%0A%0A    /**%0A     * Returns the identifier for the referenced (foreign) table.%0A     *%0A     * @return  target (foreign) table identifier%0A     */%0A    TableIdentifier%3CFK_ENTITY%3E getTableIdentifier();
 %0A    %0A  
@@ -1928,32 +1928,37 @@
  source:%0A     * 
+%3Cpre%3E
 %7B@code%0A     *   
@@ -2031,32 +2031,40 @@
 ars returns 
-Streamer
+FindFromNullable
 %3CFoo, Bar%3E%0A 
@@ -2093,32 +2093,38 @@
 h(...);%0A     * %7D
+%3C/pre%3E
 %0A     * %0A     * 
@@ -2571,36 +2571,32 @@
 tTargetField();%0A
-    
 %0A    /**%0A     * 
@@ -2607,57 +2607,596 @@
 rns 
-the identifier for the referenced (foreign) table
+%7B@code true%7D if the %7B@link #apply(Object)%7D-method will return a%0A     * stream with a value. Otherwise, %7B@code false%7D is returned.%0A     *%0A     * @param entity  the entity to locate a foreign entity for%0A     * @return        singleton or empty stream%0A     */%0A    boolean isPresent(ENTITY entity);%0A%0A    /**%0A     * Applies this method, returning the referenced entity. If no entity was%0A     * referenced, then an exception is thrown. This method should therefore not%0A     * be invoked unless the status of the availability of the entity has been%0A     * checked with %7B@link #isPresent(Object)%7D
 .%0A  
@@ -3196,32 +3196,35 @@
 t)%7D.%0A     * 
+%3Cp%3E
 %0A     * 
 @return  tar
@@ -3215,111 +3215,775 @@
   * 
-@return  target (foreign) table identifier%0A     */%0A    TableIdentifier%3CFK_ENTITY%3E getTableIdentifier(
+Another way of retrieving the referenced entity is to use the%0A     * %7B@link #apply(Object)%7D-method.%0A     *%0A     * @param entity  the entity to locate a foreign entity for%0A     * @return        the referenced foreign entity%0A     *%0A     * @throws IllegalArgumentException  if no foreign entity was referenced%0A     */%0A    FK_ENTITY applyOrThrow(ENTITY entity) throws IllegalArgumentException;%0A%0A    /**%0A     * Applies this method, locating the referenced entity and returning it as a%0A     * singleton stream if found. If no entity was referenced, an empty stream%0A     * will be returned.%0A     *%0A     * @param entity  the entity to locate a foreign entity for%0A     * @return        singleton or empty stream%0A     */%0A    @Override%0A    Stream%3CFK_ENTITY%3E apply(ENTITY entity
 );%0A
-%0A
 %7D%0A

Introduce more methods in FindFromNullable-interface