gt: 		if (!deleteSucceeded) {
context: /*
   * Copyright (c) Mirth Corporation. All rights reserved.
   * 
   * http://www.mirthcorp.com
   * 
   * The software in this package is published under the terms of the MPL license a copy of which has
   * been included with this distribution in the LICENSE.txt file.
   */
  
  package com.mirth.connect.connectors.file.filesystems;
  
  import java.io.FilenameFilter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.io.filefilter.WildcardFileFilter;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.net.ftp.FTP;
  import org.apache.commons.net.ftp.FTPClient;
  import org.apache.commons.net.ftp.FTPFile;
  import org.apache.commons.net.ftp.FTPReply;
  
  import com.mirth.connect.connectors.file.filters.RegexFilenameFilter;
  
  /**
   * The FileSystemConnection class for files accessed via FTP.
   */
  public class FtpConnection implements FileSystemConnection {
  
  	public class FtpFileInfo implements FileInfo {
  
  		String thePath;
  		FTPFile theFile;
  		
  		public FtpFileInfo(String path, FTPFile theFile) {
  			this.thePath = path;
  			this.theFile = theFile;
  		}
  
  		public long getLastModified() {
  			return theFile.getTimestamp().getTimeInMillis();
  		}
  
  		public String getName() {
  			return theFile.getName();
  		}
  
  		/** Gets the absolute pathname of the file */
  		public String getAbsolutePath() {
  			
  			return getParent() + "/" + getName();
  		}
  		
  		public String getCanonicalPath() throws IOException {
  		    throw new UnsupportedOperationException();
          }
  		
  		/** Gets the absolute pathname of the directory holding the file */
  		public String getParent() {
  			
  			return this.thePath;
  		}
  		
  		public long getSize() {
  			return theFile.getSize();
  		}
  
  		public boolean isDirectory() {
  			return theFile.isDirectory();
  		}
  
  		public boolean isFile() {
  			return theFile.isFile();
  		}
  
  		public boolean isReadable() {
  			return true;
  			// return theFile.hasPermission(access, permission);
  		}
  		
  	}
  	
  	private static transient Log logger = LogFactory.getLog(FtpConnection.class);
  
  	/** The apache commons FTP client instance */
  	private FTPClient client = null;
  
  	public FtpConnection(String host, int port, String username, String password, boolean passive, int timeout) throws Exception {
  		client = new FTPClient();
  		
  		// This sets the timeout for the initial connection.
  		client.setConnectTimeout(timeout);
  		
  		try {
  			if (port > 0) {
  				client.connect(host, port);
  			} else {
  				client.connect(host);
  			}
  			
  			// XXX: As per JavaDoc comments, you should only call this after the connection has been opened by connect()
  			client.setSoTimeout(timeout);
  			
  			if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
  				throw new IOException("Ftp error: " + client.getReplyCode());
  			}
  			if (!client.login(username, password)) {
  				throw new IOException("Ftp error: " + client.getReplyCode());
  			}
  			if (!client.setFileType(FTP.BINARY_FILE_TYPE)) {
  				throw new IOException("Ftp error");
  			}
  			if (passive) {
  				client.enterLocalPassiveMode();
  			}
  		} catch (Exception e) {
  			if (client.isConnected()) {
  				client.disconnect();
  			}
  			throw e;
  		}
  	}
  
  	@Override
  	public List<FileInfo> listFiles(String fromDir, String filenamePattern, boolean isRegex, boolean ignoreDot) throws Exception {
          FilenameFilter filenameFilter;
          
          if (isRegex) {
              filenameFilter = new RegexFilenameFilter(filenamePattern);    
          } else {
              filenameFilter = new WildcardFileFilter(filenamePattern.trim().split("\\s*,\\s*"));
          }
  	    
  		if (!cwd(fromDir)) {
  			logger.error("listFiles.changeWorkingDirectory: " + client.getReplyCode() + "-" + client.getReplyString());
  			throw new IOException("Ftp error: " + client.getReplyCode());
  		}
  
  		FTPFile[] files = client.listFiles();
  		if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
  			logger.error("listFiles.listFiles: " + client.getReplyCode() + "-" + client.getReplyString());
  			throw new IOException("Ftp error: " + client.getReplyCode());
  		}
  		
  		if (files == null || files.length == 0) {
  			return new ArrayList<FileInfo>();
  		}
  		
  		List<FileInfo> v = new ArrayList<FileInfo>(files.length);
  		
  		for (int i = 0; i < files.length; i++) {
  			if ((files[i] != null) && files[i].isFile()) {
  				if ((filenameFilter == null || filenameFilter.accept(null, files[i].getName())) && !(ignoreDot && files[i].getName().startsWith("."))) {
  				        v.add(new FtpFileInfo(fromDir, files[i]));    
  				}
  			}
  		}
  		return v;
  	}
  	
  	@Override
      public List<String> listDirectories(String fromDir) throws Exception {
          List<String> directories = new ArrayList<String>();
          
          if (!cwd(fromDir)) {
              logger.error("listFiles.changeWorkingDirectory: " + client.getReplyCode() + "-" + client.getReplyString());
              throw new IOException("Ftp error: " + client.getReplyCode());
          }
  
          FTPFile[] ftpDirectories = client.listDirectories();
          if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
              logger.error("listFiles.listFiles: " + client.getReplyCode() + "-" + client.getReplyString());
              throw new IOException("Ftp error: " + client.getReplyCode());
          }
          
          for (FTPFile directory : ftpDirectories) {
              if (directory != null) {
                  directories.add(new FtpFileInfo(fromDir, directory).getAbsolutePath());
              }
          }
          
          return directories;
      }
  	
      @Override
      public boolean exists(String file, String path) {
          try {
              FTPFile[] files = client.listFiles(path + "/" + file);
              return ((files != null) && (files.length == 1));
          } catch (IOException e) {
              return false;
          }
      }
  
  	@Override
  	public boolean canRead(String readDir) {
  	    try {
  	        return cwd(readDir);
  	    } catch (IOException e) {
  	        return false;
  	    }
  	}
  	
  	@Override
  	public boolean canWrite(String writeDir) {
          try {
              return cwd(writeDir);
          } catch (IOException e) {
              return false;
          }
  	}
  
      // See MIRTH-1873
      private boolean cwd(String destDir) throws IOException {
          return client.changeWorkingDirectory(destDir);
      }
  	
  	@Override
  	public InputStream readFile(String file, String fromDir)
  		throws Exception
  	{
  		if (!cwd(fromDir)) {
  			logger.error("readFile.changeWorkingDirectory: " + client.getReplyCode() + "-" + client.getReplyString());
  			throw new IOException("Ftp error: " + client.getReplyCode());
  		}
  
  		return client.retrieveFileStream(file);
  	}
  
  	/** Must be called after readFile when reading is complete */
  	@Override
  	public void closeReadFile() throws Exception {
  		if (!client.completePendingCommand()) {
  			logger.error("closeReadFile.completePendingCommand: " + client.getReplyCode() + "-" + client.getReplyString());
  			throw new IOException("Ftp error: " + client.getReplyCode());
  		}
  	}
  
  	@Override
  	public boolean canAppend() {
  
  		return true;
  	}
  	
  	@Override
  	public void writeFile(String file, String toDir, boolean append, InputStream is)
  		throws Exception
  	{
  		cdmake(toDir);
  		
  		if (append) {
  		    client.appendFile(file, is);
  		} else {
  		    client.storeFile(file, is);    
  		}
  		
  		// have to close it since append or store don't close the stream
  		is.close();
  		
  	    // check the reply code to verify success
          if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
              logger.error("writeFile: " + client.getReplyString());
              throw new IOException(client.getReplyString());
          }
  	}
  
  	@Override
  	public void delete(String file, String fromDir, boolean mayNotExist)
  		throws Exception
  	{
  		if (!cwd(fromDir)) {
  			if (!mayNotExist) {
  				logger.error("delete.changeWorkingDirectory: " + client.getReplyCode() + "-" + client.getReplyString());
  				throw new IOException("Ftp error: " + client.getReplyCode());
  			} else {
  				return;
  			}
  		}
  
  		boolean deleteSucceeded = client.deleteFile(file);
  