// Path: src/main/java/com/cathive/fx/guice/fxml/FXMLComponentBuilderFactory.java
// @Singleton
// public final class FXMLComponentBuilderFactory implements BuilderFactory {
// 
//     @Inject private Injector injector;
// 
//     private static final Logger LOGGER = Logger.getLogger(FXMLComponentBuilderFactory.class.getName());
//     private final JavaFXBuilderFactory defaultBuilderFactory = new JavaFXBuilderFactory();
// 
//     @SuppressWarnings({ "rawtypes", "unchecked" })
//     @Override
//     public Builder<?> getBuilder(final Class<?> componentClass) {
//         final String className = componentClass.getName();
//         LOGGER.log(Level.FINE, "Searching builder for component class '{0}'.", className);
//         if (componentClass.isAnnotationPresent(FXMLComponent.class)) {
//             LOGGER.log(Level.FINE, "Creating FXMLComponentBuilder for class '{0}'.", className);
//             return new FXMLComponentBuilder(injector, componentClass);
//         }
//         // Fall back to the default builder factory if we are not dealing with a FXMLComponent class.
//         return defaultBuilderFactory.getBuilder(componentClass);
//     }
// 
// }
// 
// Path: src/main/java/com/cathive/fx/guice/fxml/FXMLLoadingScope.java
// @Singleton
// public final class FXMLLoadingScope implements Scope {
// 
//     private GuiceFXMLLoader fxmlLoader;
// 
//     private Set<IdentifiableController> identifiables;
// 
//     public FXMLLoadingScope() {
//         super();
//     }
// 
// 
//     /**
//      * Enter the scope. From here on in, controllers implementing
//      * {@link IdentifiableController} and annotated wih {@link FXMLController} will
//      * be retrievable from any {@link ControllerLookup} instance that is
//      * injected.
//      * @param fxmlLoader
//      *     The FXML Loader to be used within this scope.
//      */
//     public void enter(final GuiceFXMLLoader fxmlLoader) {
//         this.fxmlLoader = fxmlLoader;
//         this.identifiables = new HashSet<>();
//     }
// 
//     /**
//      * End the scope.
//      */
//     public void exit() {
//         this.identifiables = null;
//         this.fxmlLoader = null;
//     }
// 
//     @Override
//     public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
//         return new Provider<T>() {
//             @Override
//             public T get() {
//                 final T providedObject = unscoped.get();
//                 if (identifiables != null && providedObject instanceof IdentifiableController) {
//                     final IdentifiableController identifiable = (IdentifiableController) providedObject;
//                     identifiables.add(identifiable);
//                 }
//                 return providedObject;
//             }
//         };
//     }
// 
// 	public <T> T getInstance(final String controllerId) {
//         for (final IdentifiableController identifiable: identifiables) {
//             if (identifiable.getId().equals(controllerId)) {
//                 return (T) identifiable;
//             }
//         }
//         // TODO Throw an exception maybe?
//         return null;
//     }
// 
//     public Collection<IdentifiableController> getIdentifiables() {
//         return identifiables;
//     }
// 
//     /**
//      * Checks whether the FXML Loading Scope is currently being used.
//      * @return {@code true} if this scope is currently active, {@code false} otherwise.
//      */
//     public boolean isActive() {
//         return (identifiables != null);
//     }
// 
// }


import com.cathive.fx.guice.fxml.FXMLComponentBuilderFactory;
import com.cathive.fx.guice.fxml.FXMLLoadingScope;
import com.google.inject.Inject;
import com.google.inject.Injector;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ResourceBundle;
     * {@link javafx.fxml.FXMLLoader#load(URL) load method}
     * of JavaFX' FXMLLoader class that adds a tiny notch of Guice-related
     * magic.</p>
     * 
     * @param url
     *             URL of the FXML resource to be loaded.
     * @return
     *             The loaded object hierarchy encapsulated in a special result object.
     * @throws IOException
     * @see javafx.fxml.FXMLLoader#load(URL)
     */
    public Result load(final URL url) throws IOException {
        // Delegates method call.
        return load(url, null);
    }


    /**
     * A simple wrapper around the result of a FXML loading operation.
     * @author Benjamin P. Jung
     */
    public static final class Result {

        private final ReadOnlyObjectWrapper<URL> location = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<ResourceBundle> resources = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Object> root = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Object> controller = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Charset> charset = new ReadOnlyObjectWrapper<>();

        public ReadOnlyObjectProperty<URL> locationProperty() {
// Path: src/main/java/com/cathive/fx/guice/fxml/FXMLComponentBuilderFactory.java
// @Singleton
// public final class FXMLComponentBuilderFactory implements BuilderFactory {
// 
//     @Inject private Injector injector;
// 
//     private static final Logger LOGGER = Logger.getLogger(FXMLComponentBuilderFactory.class.getName());
//     private final JavaFXBuilderFactory defaultBuilderFactory = new JavaFXBuilderFactory();
// 
//     @SuppressWarnings({ "rawtypes", "unchecked" })
//     @Override
//     public Builder<?> getBuilder(final Class<?> componentClass) {
//         final String className = componentClass.getName();
//         LOGGER.log(Level.FINE, "Searching builder for component class '{0}'.", className);
//         if (componentClass.isAnnotationPresent(FXMLComponent.class)) {
//             LOGGER.log(Level.FINE, "Creating FXMLComponentBuilder for class '{0}'.", className);
//             return new FXMLComponentBuilder(injector, componentClass);
//         }
//         // Fall back to the default builder factory if we are not dealing with a FXMLComponent class.
//         return defaultBuilderFactory.getBuilder(componentClass);
//     }
// 
// }
// 
// Path: src/main/java/com/cathive/fx/guice/fxml/FXMLLoadingScope.java
// @Singleton
// public final class FXMLLoadingScope implements Scope {
// 
//     private GuiceFXMLLoader fxmlLoader;
// 
//     private Set<IdentifiableController> identifiables;
// 
//     public FXMLLoadingScope() {
//         super();
//     }
// 
// 
//     /**
//      * Enter the scope. From here on in, controllers implementing
//      * {@link IdentifiableController} and annotated wih {@link FXMLController} will
//      * be retrievable from any {@link ControllerLookup} instance that is
//      * injected.
//      * @param fxmlLoader
//      *     The FXML Loader to be used within this scope.
//      */
//     public void enter(final GuiceFXMLLoader fxmlLoader) {
//         this.fxmlLoader = fxmlLoader;
//         this.identifiables = new HashSet<>();
//     }
// 
//     /**
//      * End the scope.
//      */
//     public void exit() {
//         this.identifiables = null;
//         this.fxmlLoader = null;
//     }
// 
//     @Override
//     public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
//         return new Provider<T>() {
//             @Override
//             public T get() {
//                 final T providedObject = unscoped.get();
//                 if (identifiables != null && providedObject instanceof IdentifiableController) {
//                     final IdentifiableController identifiable = (IdentifiableController) providedObject;
//                     identifiables.add(identifiable);
//                 }
//                 return providedObject;
//             }
//         };
//     }
// 
// 	public <T> T getInstance(final String controllerId) {
//         for (final IdentifiableController identifiable: identifiables) {
//             if (identifiable.getId().equals(controllerId)) {
//                 return (T) identifiable;
//             }
//         }
//         // TODO Throw an exception maybe?
//         return null;
//     }
// 
//     public Collection<IdentifiableController> getIdentifiables() {
//         return identifiables;
//     }
// 
//     /**
//      * Checks whether the FXML Loading Scope is currently being used.
//      * @return {@code true} if this scope is currently active, {@code false} otherwise.
//      */
//     public boolean isActive() {
//         return (identifiables != null);
//     }
// 
// }


// Path: src/main/java/com/cathive/fx/guice/GuiceFXMLLoader.java
import com.cathive.fx.guice.fxml.FXMLComponentBuilderFactory;
import com.cathive.fx.guice.fxml.FXMLLoadingScope;
import com.google.inject.Inject;
import com.google.inject.Injector;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ResourceBundle;

     * {@link javafx.fxml.FXMLLoader#load(URL) load method}
     * of JavaFX' FXMLLoader class that adds a tiny notch of Guice-related
     * magic.</p>
     * 
     * @param url
     *             URL of the FXML resource to be loaded.
     * @return
     *             The loaded object hierarchy encapsulated in a special result object.
     * @throws IOException
     * @see javafx.fxml.FXMLLoader#load(URL)
     */
    public Result load(final URL url) throws IOException {
        // Delegates method call.
        return load(url, null);
    }


    /**
     * A simple wrapper around the result of a FXML loading operation.
     * @author Benjamin P. Jung
     */
    public static final class Result {

        private final ReadOnlyObjectWrapper<URL> location = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<ResourceBundle> resources = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Object> root = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Object> controller = new ReadOnlyObjectWrapper<>();
        private final ReadOnlyObjectWrapper<Charset> charset = new ReadOnlyObjectWrapper<>();

        public ReadOnlyObjectProperty<URL> locationProperty() {
            return this.location.getReadOnlyProperty();