public class Application extends android.app.Application {
    private RuntimeApplicationComponent applicationComponent;
    @Inject DependenciesInjector injector;

    @Override
    public void onCreate() {
        super.onCreate();
        initializeInjection();
    }

    private void initializeInjection() {
        applicationComponent = DaggerRuntimeApplicationComponent.builder()
                                    .runtimeApplicationModule(new RuntimeApplicationModule(this))
                                    .build();
        applicationComponent.inject(this);
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }

    public DependenciesInjector getDependenciesInjector() {
        return injector;
    }
} @Module
public class EndpointsModule {
    private static final String BASE_URL = "http://api.giphy.com/";

    @Provides @Singleton
    DashboardEndpoint provideDashboardEndpoint() {
        return getRetrofitBuilder().create(DashboardEndpoint.class);
    }

    private Retrofit getRetrofitBuilder() {
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
} @Module
public class ApiModule {
    @Provides
    DashboardApi provideDashboardApi(DashboardRetrofitApi api) {
        return api;
    }

    @Provides
    ImageResponseMapper provideImageResponseMapper(ImageResponseMapperImpl mapper) {
        return mapper;
    }
} @Module
public class TranformerModule {
    @Provides @Singleton
    ImageUriTransformer provideImageUriTransformer(GiphyImageUriTransformer transformer) {
        return transformer;
    }
} @Module
public class CachesModule {
    @Provides @Singleton
    DashboardCache provideDashboardCache(DashboardMemoryCache cache) {
        return cache;
    }
} @Module
public class DatasourcesModule {
    @Provides
    DashboardDatasource provideDashboardDatasource(DashboardCloudDatasource datasource) {
        return datasource;
    }

    @Provides
    ImageEntityMapper provideImageEntityMapper(ImageEntityMapperImpl mapper) {
        return mapper;
    }
} @Module
public class RepositoriesModule {
    @Provides @Singleton
    DashboardRepository provideDashboardRepository(DashboardRepositoryImpl repository) {
        return repository;
    }
} public class JobExecutor implements ThreadExecutor {

    private static final int INITIAL_POOL_SIZE = 3;
    private static final int MAX_POOL_SIZE = 5;
    private static final int KEEP_ALIVE_TIME = 10;
    private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

    private final BlockingQueue<Runnable> workQueue;

    private final ThreadPoolExecutor threadPoolExecutor;

    private final ThreadFactory threadFactory;

    @Inject
    public JobExecutor() {
        this.workQueue = new LinkedBlockingQueue<Runnable>();
        this.threadFactory = new JobThreadFactory();
        this.threadPoolExecutor = new ThreadPoolExecutor(INITIAL_POOL_SIZE, MAX_POOL_SIZE,
                KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, this.workQueue, this.threadFactory);
    }

    @Override
    public void execute(Runnable runnable) {
        if (runnable == null) {
            throw new IllegalArgumentException("Runnable to execute cannot be null");
        }
        this.threadPoolExecutor.execute(runnable);
    }

    private static class JobThreadFactory implements ThreadFactory {
        private static final String THREAD_NAME = "android_";
        private int counter = 0;

        @Override
        public Thread newThread(Runnable runnable) {
            return new Thread(runnable, THREAD_NAME + counter);
        }
    }
} public interface PostExecutionThread {
    void post(Runnable runnable);
} public interface ThreadExecutor extends Executor { } public class UIThread implements PostExecutionThread {
    private static class LazyHolder {
        private static final UIThread INSTANCE = new UIThread();
    }

    public static UIThread getInstance() {
        return LazyHolder.INSTANCE;
    }

    private final Handler handler;

    private UIThread() {
        this.handler = new Handler(Looper.getMainLooper());
    }

    @Override public void post(Runnable runnable) {
        handler.post(runnable);
    }
} @Module
public class InstrumentationModule {
    @Provides @Singleton
    ImageLoader provideImageLoader(GlideImageLoader imageLoader) {
        return imageLoader;
    }
}
import com.txusballesteros.testing.data.internal.di.RepositoriesModule;
import com.txusballesteros.testing.threading.JobExecutor;
import com.txusballesteros.testing.threading.PostExecutionThread;
import com.txusballesteros.testing.threading.ThreadExecutor;
import com.txusballesteros.testing.threading.UIThread;
import com.txusballesteros.testing.view.instrumentation.internal.di.InstrumentationModule;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import com.txusballesteros.testing.Application;
import com.txusballesteros.testing.data.api.endpoint.internal.di.EndpointsModule;
import com.txusballesteros.testing.data.api.internal.di.ApiModule;
import com.txusballesteros.testing.data.api.transformer.internal.di.TranformerModule;
import com.txusballesteros.testing.data.cache.internal.di.CachesModule;
import com.txusballesteros.testing.data.datasource.internal.di.DatasourcesModule;
/*
 * Copyright Txus Ballesteros 2016 (@txusballesteros)
 *
 * This file is part of some open source application.
 *
 * 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.
 *
 * Contact: Txus Ballesteros <txus.ballesteros@gmail.com>
 */
package com.txusballesteros.testing.internal.di;




@Module( includes = {
        InstrumentationModule.class,
        RepositoriesModule.class,
        DatasourcesModule.class,
        CachesModule.class,
        ApiModule.class,
        TranformerModule.class,