// 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/ConsoleDeviceParamsImpl.java
// public class ConsoleDeviceParamsImpl implements DevicesParams {
//     @Parameter(names = "--all", description = "Show all devices. By default only available devices are returned.")
//     private boolean allDevices;
//     @Parameter(names = "-abi", description = "Filter by device abi architecture")
//     private String abi;
//     @Parameter(names = "-api", description = "Filter by device api level")
//     private int apiVersion;
//     @Parameter(names = "-minApi", description = "Filter by device min api level")
//     private int minApiVersion;
//     @Parameter(names = "-maxApi", description = "Filter by device max api level")
//     private int maxApiVersion;
//     @Parameter(names = "-count", description = "Filter devices by count")
//     private int count;
//     @Parameter(names = "-name", description = "Filter devices by its name", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription nameFilterDescription;
//     @Parameter(names = "-provider", description = "Filter devices by provider", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription providerFilterDescription;
//     @Parameter(names = "-serial", description = "Filter devices by serial number", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription serialFilterDescription;
// 
//     @Override
//     public boolean isAllDevices() {
//         return allDevices;
//     }
// 
//     @Override
//     public String getAbi() {
//         return abi;
//     }
// 
//     @Override
//     public int getApiVersion() {
//         return apiVersion;
//     }
// 
//     @Override
//     public int getMinApiVersion() {
//         return minApiVersion;
//     }
// 
//     @Override
//     public int getMaxApiVersion() {
//         return maxApiVersion;
//     }
// 
//     @Override
//     public int getCount() {
//         return count;
//     }
// 
//     @Override
//     public StringsFilterDescription getNameFilterDescription() {
//         return nameFilterDescription;
//     }
// 
//     @Override
//     public StringsFilterDescription getProviderFilterDescription() {
//         return providerFilterDescription;
//     }
// 
//     @Override
//     public StringsFilterDescription getSerialFilterDescription() {
//         return serialFilterDescription;
//     }
// }
// 
// 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.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
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.ConsoleDeviceParamsImpl;
import com.github.e13mort.stf.console.commands.cache.DeviceListCache;
import io.reactivex.Completable;
import java.io.OutputStream;
package com.github.e13mort.stf.console.commands.devices;



@Parameters(commandDescription = "Print list of available devices")
public class DevicesCommand implements CommandContainer.Command {
    private final FarmClient client;
    private final OutputStream output;

    @ParametersDelegate
    private DevicesParams params = new ConsoleDeviceParamsImpl();

    @Parameter(names = {"--my-columns"}, description = "<BETA> Use columns from web panel")
    private boolean userColumns;
    private DeviceListCache cache;

    public DevicesCommand(FarmClient client, DeviceListCache cache, OutputStream output) {
        this.client = client;
        this.cache = cache;
        this.output = output;
    }

    @Override
    public Completable execute() {
// 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/ConsoleDeviceParamsImpl.java
// public class ConsoleDeviceParamsImpl implements DevicesParams {
//     @Parameter(names = "--all", description = "Show all devices. By default only available devices are returned.")
//     private boolean allDevices;
//     @Parameter(names = "-abi", description = "Filter by device abi architecture")
//     private String abi;
//     @Parameter(names = "-api", description = "Filter by device api level")
//     private int apiVersion;
//     @Parameter(names = "-minApi", description = "Filter by device min api level")
//     private int minApiVersion;
//     @Parameter(names = "-maxApi", description = "Filter by device max api level")
//     private int maxApiVersion;
//     @Parameter(names = "-count", description = "Filter devices by count")
//     private int count;
//     @Parameter(names = "-name", description = "Filter devices by its name", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription nameFilterDescription;
//     @Parameter(names = "-provider", description = "Filter devices by provider", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription providerFilterDescription;
//     @Parameter(names = "-serial", description = "Filter devices by serial number", converter = FilterDescriptionConverterImpl.class)
//     private StringsFilterDescription serialFilterDescription;
// 
//     @Override
//     public boolean isAllDevices() {
//         return allDevices;
//     }
// 
//     @Override
//     public String getAbi() {
//         return abi;
//     }
// 
//     @Override
//     public int getApiVersion() {
//         return apiVersion;
//     }
// 
//     @Override
//     public int getMinApiVersion() {
//         return minApiVersion;
//     }
// 
//     @Override
//     public int getMaxApiVersion() {
//         return maxApiVersion;
//     }
// 
//     @Override
//     public int getCount() {
//         return count;
//     }
// 
//     @Override
//     public StringsFilterDescription getNameFilterDescription() {
//         return nameFilterDescription;
//     }
// 
//     @Override
//     public StringsFilterDescription getProviderFilterDescription() {
//         return providerFilterDescription;
//     }
// 
//     @Override
//     public StringsFilterDescription getSerialFilterDescription() {
//         return serialFilterDescription;
//     }
// }
// 
// 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/main/java/com/github/e13mort/stf/console/commands/devices/DevicesCommand.java
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
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.ConsoleDeviceParamsImpl;
import com.github.e13mort.stf.console.commands.cache.DeviceListCache;
import io.reactivex.Completable;
import java.io.OutputStream;

package com.github.e13mort.stf.console.commands.devices;



@Parameters(commandDescription = "Print list of available devices")
public class DevicesCommand implements CommandContainer.Command {
    private final FarmClient client;
    private final OutputStream output;

    @ParametersDelegate
    private DevicesParams params = new ConsoleDeviceParamsImpl();

    @Parameter(names = {"--my-columns"}, description = "<BETA> Use columns from web panel")
    private boolean userColumns;
    private DeviceListCache cache;

    public DevicesCommand(FarmClient client, DeviceListCache cache, OutputStream output) {
        this.client = client;
        this.cache = cache;
        this.output = output;
    }

    @Override
    public Completable execute() {
        DocumentsLoader loader = new DocumentsLoader(client, params);