// Path: client/src/main/java/com/github/e13mort/stf/console/commands/CommandContainer.java
// public class CommandContainer {
// 
//     private Map<String, Command> commandMap = new HashMap<>();
// 
//     public CommandContainer(StfCommanderContext c) {
//         commandMap.put("devices", new DevicesCommand(c.getClient(), c.getCache(), c.getOutput()));
//         commandMap.put("connect", new ConnectCommand(c.getClient(), c.getAdbRunner(), c.getCache(), c.getLogger()));
//         commandMap.put("disconnect", new DisconnectCommand(c.getClient(), c.getLogger()));
//     }
// 
//     public Command getCommand(String operation) {
//         return commandMap.get(operation);
//     }
// 
//     public Collection<String> getAllCommands() {
//         return commandMap.keySet();
//     }
// 
//     public interface Command {
//         Completable execute();
//     }
// 
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/HelpCommandCreator.java
// public interface HelpCommandCreator {
//     CommandContainer.Command createHelpCommand(JCommander commander);
// 
//     class HelpCommandCreatorImpl implements HelpCommandCreator {
//         @Override
//         public CommandContainer.Command createHelpCommand(JCommander commander) {
//             return new HelpCommand(commander);
//         }
//     }
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/UnknownCommandException.java
// public class UnknownCommandException extends Exception {
//     public UnknownCommandException(String message) {
//         super(message);
//     }
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/cache/DeviceListCache.java
// public interface DeviceListCache {
//     static DeviceListCache getCache() {
//         return new DeviceListCacheImpl();
//     }
// 
//     DeviceListCache EMPTY = new DeviceListCache() {
//         @Override
//         public CacheTransaction beginTransaction() {
//             return CacheTransaction.EMPTY;
//         }
// 
//         @Override
//         public List<Device> getCachedFiles() {
//             return Collections.emptyList();
//         }
//     };
// 
//     CacheTransaction beginTransaction();
// 
//     List<Device> getCachedFiles();
// 
//     interface CacheTransaction {
//         CacheTransaction EMPTY = new CacheTransaction() {
//             @Override
//             public void addDevice(Device device) {
// 
//             }
// 
//             @Override
//             public void save() {
// 
//             }
//         };
// 
//         void addDevice(Device device);
// 
//         void save();
//     }
// }


import com.beust.jcommander.JCommander;
import com.github.e13mort.stf.client.FarmClient;
import com.github.e13mort.stf.client.parameters.DevicesParams;
import com.github.e13mort.stf.console.commands.CommandContainer;
import com.github.e13mort.stf.console.commands.HelpCommandCreator;
import com.github.e13mort.stf.console.commands.UnknownCommandException;
import com.github.e13mort.stf.console.commands.cache.DeviceListCache;
import com.github.e13mort.stf.model.device.Device;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.logging.Logger;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
    protected CommandContainer.Command helpCommand;
    @Mock
    protected DeviceListCache cache;
    @Mock
    protected ErrorHandler errorHandler;
    @Mock
    protected DeviceListCache.CacheTransaction cacheTransaction;
    @Mock
    private HelpCommandCreator helpCommandCreator;
    @Mock
    protected OutputStream outputStream;
    @Mock
    protected Logger logger;
    @Mock
    private Device myDevice;

    @BeforeEach
    protected void setUp() throws IOException {
        MockitoAnnotations.initMocks(this);
        when(farmClient.getDevices(any(DevicesParams.class))).thenReturn(Flowable.empty());
        when(farmClient.connectToDevices(any(DevicesParams.class))).thenReturn(Flowable.empty());
        when(farmClient.disconnectFromAllDevices()).thenReturn(Flowable.empty());
        when(helpCommand.execute()).thenReturn(Completable.complete());
        when(helpCommandCreator.createHelpCommand(any(JCommander.class))).thenReturn(helpCommand);
        when(farmClient.getMyDevices()).thenReturn(Flowable.fromArray(myDevice));
        when(myDevice.getRemoteConnectUrl()).thenReturn(TEST_DEVICE_REMOTE);
        when(cache.beginTransaction()).thenReturn(cacheTransaction);
        when(cache.getCachedFiles()).thenReturn(Collections.emptyList());
    }

// Path: client/src/main/java/com/github/e13mort/stf/console/commands/CommandContainer.java
// public class CommandContainer {
// 
//     private Map<String, Command> commandMap = new HashMap<>();
// 
//     public CommandContainer(StfCommanderContext c) {
//         commandMap.put("devices", new DevicesCommand(c.getClient(), c.getCache(), c.getOutput()));
//         commandMap.put("connect", new ConnectCommand(c.getClient(), c.getAdbRunner(), c.getCache(), c.getLogger()));
//         commandMap.put("disconnect", new DisconnectCommand(c.getClient(), c.getLogger()));
//     }
// 
//     public Command getCommand(String operation) {
//         return commandMap.get(operation);
//     }
// 
//     public Collection<String> getAllCommands() {
//         return commandMap.keySet();
//     }
// 
//     public interface Command {
//         Completable execute();
//     }
// 
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/HelpCommandCreator.java
// public interface HelpCommandCreator {
//     CommandContainer.Command createHelpCommand(JCommander commander);
// 
//     class HelpCommandCreatorImpl implements HelpCommandCreator {
//         @Override
//         public CommandContainer.Command createHelpCommand(JCommander commander) {
//             return new HelpCommand(commander);
//         }
//     }
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/UnknownCommandException.java
// public class UnknownCommandException extends Exception {
//     public UnknownCommandException(String message) {
//         super(message);
//     }
// }
// 
// Path: client/src/main/java/com/github/e13mort/stf/console/commands/cache/DeviceListCache.java
// public interface DeviceListCache {
//     static DeviceListCache getCache() {
//         return new DeviceListCacheImpl();
//     }
// 
//     DeviceListCache EMPTY = new DeviceListCache() {
//         @Override
//         public CacheTransaction beginTransaction() {
//             return CacheTransaction.EMPTY;
//         }
// 
//         @Override
//         public List<Device> getCachedFiles() {
//             return Collections.emptyList();
//         }
//     };
// 
//     CacheTransaction beginTransaction();
// 
//     List<Device> getCachedFiles();
// 
//     interface CacheTransaction {
//         CacheTransaction EMPTY = new CacheTransaction() {
//             @Override
//             public void addDevice(Device device) {
// 
//             }
// 
//             @Override
//             public void save() {
// 
//             }
//         };
// 
//         void addDevice(Device device);
// 
//         void save();
//     }
// }


// Path: client/src/test/java/com/github/e13mort/stf/console/BaseStfCommanderTest.java
import com.beust.jcommander.JCommander;
import com.github.e13mort.stf.client.FarmClient;
import com.github.e13mort.stf.client.parameters.DevicesParams;
import com.github.e13mort.stf.console.commands.CommandContainer;
import com.github.e13mort.stf.console.commands.HelpCommandCreator;
import com.github.e13mort.stf.console.commands.UnknownCommandException;
import com.github.e13mort.stf.console.commands.cache.DeviceListCache;
import com.github.e13mort.stf.model.device.Device;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.logging.Logger;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

    protected CommandContainer.Command helpCommand;
    @Mock
    protected DeviceListCache cache;
    @Mock
    protected ErrorHandler errorHandler;
    @Mock
    protected DeviceListCache.CacheTransaction cacheTransaction;
    @Mock
    private HelpCommandCreator helpCommandCreator;
    @Mock
    protected OutputStream outputStream;
    @Mock
    protected Logger logger;
    @Mock
    private Device myDevice;

    @BeforeEach
    protected void setUp() throws IOException {
        MockitoAnnotations.initMocks(this);
        when(farmClient.getDevices(any(DevicesParams.class))).thenReturn(Flowable.empty());
        when(farmClient.connectToDevices(any(DevicesParams.class))).thenReturn(Flowable.empty());
        when(farmClient.disconnectFromAllDevices()).thenReturn(Flowable.empty());
        when(helpCommand.execute()).thenReturn(Completable.complete());
        when(helpCommandCreator.createHelpCommand(any(JCommander.class))).thenReturn(helpCommand);
        when(farmClient.getMyDevices()).thenReturn(Flowable.fromArray(myDevice));
        when(myDevice.getRemoteConnectUrl()).thenReturn(TEST_DEVICE_REMOTE);
        when(cache.beginTransaction()).thenReturn(cacheTransaction);
        when(cache.getCachedFiles()).thenReturn(Collections.emptyList());
    }

    protected DevicesParams runDeviceParamsTest(DeviceParamsProducingCommand source, String params) throws IOException, UnknownCommandException {