// Path: src/main/java/com/github/xsavikx/androidscreencast/api/file/FileInfo.java
// @Singleton
// public final class FileInfo {
// 
//     public AndroidDeviceImpl device;
//     public String path;
//     public String attribs;
//     public boolean directory;
//     public String name;
// 
//     @Inject
//     public FileInfo() {
//     }
// 
//     public File downloadTemporary() {
//         try {
//             File tempFile = File.createTempFile("android", name);
//             device.pullFile(path + name, tempFile);
//             tempFile.deleteOnExit();
//             return tempFile;
//         } catch (IOException ex) {
//             throw new IORuntimeException(ex);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return name;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/api/injector/OutputStreamShellOutputReceiver.java
// public final class OutputStreamShellOutputReceiver implements IShellOutputReceiver {
// 
//     private final OutputStream os;
// 
//     public OutputStreamShellOutputReceiver(OutputStream os) {
//         this.os = os;
//     }
// 
//     @Override
//     public void addOutput(byte[] buf, int off, int len) {
//         try {
//             os.write(buf, off, len);
//         } catch (IOException e) {
//             throw new IORuntimeException(e);
//         }
//     }
// 
//     @Override
//     public void flush() {
//         try {
//             os.flush();
//         } catch (IOException e) {
//             throw new IORuntimeException(e);
//         }
//     }
// 
//     @Override
//     public boolean isCancelled() {
//         return false;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/exception/AndroidScreenCastRuntimeException.java
// public class AndroidScreenCastRuntimeException extends RuntimeException {
// 
//     private String additionalInformation;
// 
//     public AndroidScreenCastRuntimeException() {
//     }
// 
//     public AndroidScreenCastRuntimeException(String message) {
//         super(message);
//     }
// 
// 
//     public AndroidScreenCastRuntimeException(String message, String additionalInformation) {
//         super(message);
//         this.additionalInformation = additionalInformation;
//     }
// 
//     public AndroidScreenCastRuntimeException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public AndroidScreenCastRuntimeException(Throwable cause) {
//         super(cause);
//     }
// 
//     public AndroidScreenCastRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
//     public String getAdditionalInformation() {
//         return additionalInformation;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/exception/ExecuteCommandException.java
// public final class ExecuteCommandException extends AndroidScreenCastRuntimeException {
// 
//     public ExecuteCommandException(String command) {
//         super(String.format("Cannot execute command '%s'.", command));
//     }
// }


import java.util.ArrayList;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.SyncService;
import com.github.xsavikx.androidscreencast.api.file.FileInfo;
import com.github.xsavikx.androidscreencast.api.injector.OutputStreamShellOutputReceiver;
import com.github.xsavikx.androidscreencast.exception.AndroidScreenCastRuntimeException;
import com.github.xsavikx.androidscreencast.exception.ExecuteCommandException;
import org.slf4j.Logger;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.charset.StandardCharsets;
    }

    @Override
    public List<FileInfo> list(final String path) {
        log().debug("Listing files under path: `{}`.", path);
        try {
            final String s = executeCommand("ls -l " + path);
            final String[] entries = s.split("\r\n");
            final List<FileInfo> fileInfos = new ArrayList<>();
            for (final String entry : entries) {
                String[] data = entry.split(" ");
                if (data.length < 4)
                    continue;
                String attributes = data[0];
                boolean directory = attributes.charAt(0) == 'd';
                String name = data[data.length - 1];

                final FileInfo fi = new FileInfo();
                fi.attribs = attributes;
                fi.directory = directory;
                fi.name = name;
                fi.path = path;
                fi.device = this;

                fileInfos.add(fi);
            }
            log().debug("Found `{}` files under path `{}`.", fileInfos.size(), path);
            return fileInfos;
        } catch (final Exception ex) {
            log().error("Unable to list files under path `{}`.", path, ex);
// Path: src/main/java/com/github/xsavikx/androidscreencast/api/file/FileInfo.java
// @Singleton
// public final class FileInfo {
// 
//     public AndroidDeviceImpl device;
//     public String path;
//     public String attribs;
//     public boolean directory;
//     public String name;
// 
//     @Inject
//     public FileInfo() {
//     }
// 
//     public File downloadTemporary() {
//         try {
//             File tempFile = File.createTempFile("android", name);
//             device.pullFile(path + name, tempFile);
//             tempFile.deleteOnExit();
//             return tempFile;
//         } catch (IOException ex) {
//             throw new IORuntimeException(ex);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return name;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/api/injector/OutputStreamShellOutputReceiver.java
// public final class OutputStreamShellOutputReceiver implements IShellOutputReceiver {
// 
//     private final OutputStream os;
// 
//     public OutputStreamShellOutputReceiver(OutputStream os) {
//         this.os = os;
//     }
// 
//     @Override
//     public void addOutput(byte[] buf, int off, int len) {
//         try {
//             os.write(buf, off, len);
//         } catch (IOException e) {
//             throw new IORuntimeException(e);
//         }
//     }
// 
//     @Override
//     public void flush() {
//         try {
//             os.flush();
//         } catch (IOException e) {
//             throw new IORuntimeException(e);
//         }
//     }
// 
//     @Override
//     public boolean isCancelled() {
//         return false;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/exception/AndroidScreenCastRuntimeException.java
// public class AndroidScreenCastRuntimeException extends RuntimeException {
// 
//     private String additionalInformation;
// 
//     public AndroidScreenCastRuntimeException() {
//     }
// 
//     public AndroidScreenCastRuntimeException(String message) {
//         super(message);
//     }
// 
// 
//     public AndroidScreenCastRuntimeException(String message, String additionalInformation) {
//         super(message);
//         this.additionalInformation = additionalInformation;
//     }
// 
//     public AndroidScreenCastRuntimeException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public AndroidScreenCastRuntimeException(Throwable cause) {
//         super(cause);
//     }
// 
//     public AndroidScreenCastRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
//     public String getAdditionalInformation() {
//         return additionalInformation;
//     }
// }
// 
// Path: src/main/java/com/github/xsavikx/androidscreencast/exception/ExecuteCommandException.java
// public final class ExecuteCommandException extends AndroidScreenCastRuntimeException {
// 
//     public ExecuteCommandException(String command) {
//         super(String.format("Cannot execute command '%s'.", command));
//     }
// }


// Path: src/main/java/com/github/xsavikx/androidscreencast/api/AndroidDeviceImpl.java
import java.util.ArrayList;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.SyncService;
import com.github.xsavikx.androidscreencast.api.file.FileInfo;
import com.github.xsavikx.androidscreencast.api.injector.OutputStreamShellOutputReceiver;
import com.github.xsavikx.androidscreencast.exception.AndroidScreenCastRuntimeException;
import com.github.xsavikx.androidscreencast.exception.ExecuteCommandException;
import org.slf4j.Logger;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.charset.StandardCharsets;

    }

    @Override
    public List<FileInfo> list(final String path) {
        log().debug("Listing files under path: `{}`.", path);
        try {
            final String s = executeCommand("ls -l " + path);
            final String[] entries = s.split("\r\n");
            final List<FileInfo> fileInfos = new ArrayList<>();
            for (final String entry : entries) {
                String[] data = entry.split(" ");
                if (data.length < 4)
                    continue;
                String attributes = data[0];
                boolean directory = attributes.charAt(0) == 'd';
                String name = data[data.length - 1];

                final FileInfo fi = new FileInfo();
                fi.attribs = attributes;
                fi.directory = directory;
                fi.name = name;
                fi.path = path;
                fi.device = this;

                fileInfos.add(fi);
            }
            log().debug("Found `{}` files under path `{}`.", fileInfos.size(), path);
            return fileInfos;
        } catch (final Exception ex) {
            log().error("Unable to list files under path `{}`.", path, ex);
            throw new AndroidScreenCastRuntimeException(ex);