/*******************************************************************************
 * Copyright (c) 2010, 2018 IBM Corporation
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial implementation
 *    IBM Corporation/Andrew Johnson - Updates to use reflection for non-standard classes
 *    IBM Corporation/Andrew Johnson - Improved exception handling and hprof support
 *******************************************************************************/
package org.eclipse.mat.ibmvm.acquire;

import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.query.annotations.Help;
import org.eclipse.mat.query.annotations.HelpUrl;
import org.eclipse.mat.query.annotations.Name;
import org.eclipse.mat.snapshot.acquire.VmInfo;
import org.eclipse.mat.util.IProgressListener;
import org.eclipse.mat.util.IProgressListener.Severity;

//import com.ibm.tools.attach.AgentInitializationException;
//import com.ibm.tools.attach.AgentLoadException;
//import com.ibm.tools.attach.AgentNotSupportedException;
//import com.ibm.tools.attach.AttachOperationFailedException;
//import com.ibm.tools.attach.VirtualMachine;
//import com.ibm.tools.attach.VirtualMachineDescriptor;
//import com.ibm.tools.attach.spi.AttachProvider;

/**
 * Base class for generating dumps on IBM VMs.
 * This class uses reflection to call the com.ibm or com.sun classes.
 * Be sure to update IBMExecDumpProvider.getExecJar() when any classes are added here.
 * @author ajohnson
 *
 */
@Name("IBM Dump (using attach API)")
@Help("help for IBM Dump (using attach API)")
@HelpUrl("/org.eclipse.mat.ui.help/tasks/acquiringheapdump.html#task_acquiringheapdump__2")
public class IBMDumpProvider extends BaseProvider
{
    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class AgentLoadException extends Exception
    {
        private static final long serialVersionUID = 1L;

        /**
         * Construct the exception from the
         * com.ibm.tools.attach.AgentLoadException or
         * com.sun.tools.attach.AgentLoadException object.
         *
         * @param e
         */
        AgentLoadException(Throwable e)
        {
            super(e.getMessage());
            initCause(e);
        }
    }

    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class AgentInitializationException extends Exception
    {
        private static final long serialVersionUID = 1L;

        /*
         * Construct the exception from the
         * com.ibm.tools.attach.AgentInitializationException or
         * com.sun.tools.attach.AgentInitializationException object.
         */
        AgentInitializationException(Throwable e)
        {
            super(e.getMessage()+" returnValue="+VirtualMachine.call(e, "returnValue"));
            initCause(e);
        }

        int returnValue()
        {
            return (Integer)VirtualMachine.call(getCause(), "returnValue");
        }
    }

    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class AttachNotSupportedException extends Exception
    {
        private static final long serialVersionUID = 1L;

        /**
         * Construct the exception from the
         * com.ibm.tools.attach.AttachNotSupportedException or
         * com.sun.tools.attach.AttachNotSupportedException object.
         *
         * @param e
         */
        AttachNotSupportedException(Throwable e)
        {
            super(e.getMessage());
            initCause(e);
        }
    }

    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class AttachOperationFailedException extends IOException
    {
    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
        private static final long serialVersionUID = 1L;

        /**
         * Construct the exception from the
         * com.ibm.tools.attach.AttachNotSupportedException or
         * com.sun.tools.attach.AttachNotSupportedException object.
         *
         * @param e
         */
        AttachOperationFailedException (Throwable e)
        {
            super(e.getMessage());
            initCause(e);
        }
    }

    static class VirtualMachineDescriptor
    {
        String name;
        String id;
        String displayName;
        /** A wrapper version of the provider */
        AttachProvider pr;
        /** The wrapped object */
        Object vmd;

        /**
         * Construct the exception from the
         * com.ibm.tools.attach.VirtualMachineDescriptor or
         * com.sun.tools.attach.VirtualMachineDescriptor object.
         *
         * @param vmd
         *            The object to wrap.
         */
        VirtualMachineDescriptor(Object vmd)
        {
            this.vmd = vmd;
            this.pr = new AttachProvider(VirtualMachine.call(vmd, "provider"));
            this.id = (String) VirtualMachine.call(vmd, "id");
            this.displayName = (String) (String) VirtualMachine.call(vmd, "displayName");
        }

        String displayName()
        {
            return displayName;
        }

        String id()
        {
            return id;
        }

        AttachProvider provider()
        {
            return pr;
        }
    }

    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class AttachProvider
    {
        /** The wrapper object */
        Object ap;

        /**
         * Construct a wrapper instance from from the com.ibm or com.sun
         * version: com.ibm.tools.attach.AttachProvider or
         * com.sun.tools.attach.AttachProvider
         *
         * @param o
         *            the object to wrap
         */
        AttachProvider(Object o)
        {
            ap = o;
        }

        /**
         * Attach to the virtual machine
         *
         * @param vmd
         *            A wrapped version of the descriptor
         * @return a wrapped version of the VirtualMachine
         * @throws IOException
         */
        VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd)
                        throws IOException, AttachNotSupportedException
        {
            Object o;
            try
            {
                o = VirtualMachine.call(ap, "attachVirtualMachine", vmd.vmd);
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                // Change the type
                if (VirtualMachine.isSubclassOf(t, "AttachNotSupportedException"))
                {
                    throw new AttachNotSupportedException(t);
                }
                if (VirtualMachine.isSubclassOf(t, "AttachOperationFailedException"))
                {
                    throw new AttachOperationFailedException(t);
                }
                if (t instanceof IOException)
                {
                    if (t.getMessage().contains("not attach to current VM"))
                    {
                        // Java 9/10 throws IOException instead of more useful AttachNotSupportedException
                        throw new AttachNotSupportedException(t);
                    }
                    throw (IOException)t;
                }
                throw e;
            }
            return new VirtualMachine(o);
        }

        String name()
        {
            return (String) VirtualMachine.call(ap, "name");
        }

        String type()
        {
            return (String) VirtualMachine.call(ap, "type");
        }

        private static Class<?>attCls;
        private static Class<?> getStaticClass() throws LinkageError
        {
            if (attCls == null)
            {
                attCls = VirtualMachine.getClass("com.ibm.tools.attach.spi.AttachProvider", "com.sun.tools.attach.spi.AttachProvider");
            }
            return attCls;
        }

        static List<AttachProvider>providers()
        {
            Class<?>apc = getStaticClass();
            List<?> l = (List<?>)VirtualMachine.call(apc, "providers");
            List<AttachProvider>ret = new ArrayList<AttachProvider>(l.size());
            for (Object o : l)
            {
                AttachProvider ap = new AttachProvider(o);
                ret.add(ap);
            }
            return ret;
        }

        List<VirtualMachineDescriptor>listVirtualMachines()
        {
            List<?> l = (List<?>)VirtualMachine.call(ap, "listVirtualMachines");
            List<VirtualMachineDescriptor>ret = new ArrayList<VirtualMachineDescriptor>(l.size());
            for (Object o : l)
            {
                VirtualMachineDescriptor vmd = new VirtualMachineDescriptor(o);
                ret.add(vmd);
            }
            return ret;
        }

        public String toString()
        {
            return name()+ " " + type();
        }

    }

    /**
     * Wrapper class for com.ibm.tools.attach/com.sun.tools.attach version.
     */
    static class VirtualMachine
    {
        /**
         * Helper for converting exceptions.
         *
         * @param e
         *            The exception
         * @param classname
         *            Detect if e or a superclass class has this name.
         * @return
         */
        static boolean isSubclassOf(Throwable e, String classname)
        {
            for (Class<?> o = e.getClass(); o != null; o = o.getSuperclass())
            {
                if (o.getSimpleName().equals(classname)) { return true; }
            }
            return false;
        }

        /**
         * Helper to call a method via reflection.
         *
         * @param o
         *            The object or null for static methods.
         * @param method
         *            The method name
         * @param args
         *            The arguments
         * @return
         */
        static Object call(Object o, String method, Object... args)
        {
            // Find the argument types.
            Class<?> types[] = new Class[args.length];
            for (int i = 0; i < args.length; ++i)
            {
                types[i] = args[i] != null ? args[i].getClass() : null;
            }
            Method m = null;
            Method ms[];
            Class<? extends Object> cls;
            // Presume a class object is for a static method
            if (o instanceof Class)
            {
                cls = ((Class<?>) o);
            }
            else
            {
                cls = o.getClass();
            }
            // Find a public class we can call methods from.
            // The ibm. is to exclude IBM Java 9 classes which are public but not accessible
            while (!Modifier.isPublic(cls.getModifiers()) || cls.getPackage().getName().startsWith("ibm.") || cls.getPackage().getName().startsWith("sun."))
            {
                cls = cls.getSuperclass();
            }
            ms = cls.getMethods();
            // Don't worry about interfaces for the moment
            l: for (Method m1 : ms)
            {
                int mods = m1.getModifiers();
                if (m1.getName().equals(method) && m1.getParameterTypes().length == types.length
                                && Modifier.isPublic(mods) && Modifier.isPublic(m1.getDeclaringClass().getModifiers()))
                {
                    // Match the parameters
                    for (int i = 0; i < types.length; ++i)
                    {
                        Class<?> t = m1.getParameterTypes()[i];
                        if (types[i] != null && !t.isAssignableFrom(types[i]))
                        {
                            continue l;
                        }
                    }
                    if (m == null)
                    {
                        m = m1;
                    }
                    else
                    {
                        // duplicate, so uncertain
                        m = null;
                        break;
                    }
                }
            }
            // Not found or duplicate, so do direct search and generate error if
            // needed
            if (m == null)
            {
                try
                {
                    if (o instanceof Class)
                    {
                        m = ((Class<?>) o).getMethod(method, types);
                    }
                    else
                    {
                        // This might not work if the argument is a superclass,
                        // or the parameter is an interface
                        m = o.getClass().getMethod(method, types);
                    }
                }
                catch (NoSuchMethodException e)
                {
                    // Fix up the error
                    LinkageError l = new LinkageError();
                    l.initCause(e);
                    throw l;
                }
            }
            Object ret;
            try
            {
                ret = m.invoke(o, args);
            }
            catch (IllegalAccessException e)
            {
                IllegalArgumentException e2 = new IllegalArgumentException("Object:" + o + " method:" + m + " exception:" + e);
                e2.initCause(e);
                throw e2;
            }
            catch (InvocationTargetException e)
            {
                if (e.getCause() instanceof RuntimeException)
                {
                    throw (RuntimeException)e.getCause();
                }
                else if (e.getCause() instanceof Error)
                {
                    throw (Error)e.getCause();
                }
                else
                {
                    throw new UndeclaredThrowableException(e.getCause());
                }
            }
            return ret;
        }

        /** The object which has been wrapped */
        Object vm;

        /**
         * Wrap a com.ibm.tools.attach.VirtualMachine or
         * com.sun.tools.attach.VirtualMachine object
         *
         * @param o
         */
        VirtualMachine(Object o)
        {
            vm = o;
        }

        /**
         * List all the VMs
         *
         * @return a list of wrapped versions of the VMs
         */
        static List<VirtualMachineDescriptor> list()
        {
            Class<?> c1 = getStaticClass();
            List<?> l = (List<?>) call(c1, "list");
            List<VirtualMachineDescriptor> ret = new ArrayList<VirtualMachineDescriptor>();
            for (Object o : l)
            {
                VirtualMachineDescriptor vmd1 = new VirtualMachineDescriptor(o);
                ret.add(vmd1);
            }
            return ret;
        }

        /**
         * Load an agent into the VM
         *
         * @param jar
         * @param command
         * @throws IOException
         * @throws AgentLoadException
         * @throws AgentInitializationException
         */
        public void loadAgent(String jar, String command)
                        throws IOException, AgentLoadException, AgentInitializationException
        {
            try
            {
                call(vm, "loadAgent", jar, command);
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                // Change the type
                if (isSubclassOf(t, "AgentLoadException")) { throw new AgentLoadException(t); }
                if (isSubclassOf(t, "AgentInitializationException")) { throw new AgentInitializationException(t); }
                if (t instanceof IOException) { throw (IOException)t; }
                // Rethrow
                throw e;
            }
        }

        /**
         * Load an agent into the VM
         *
         * @param lib executable library
         * @param command to pass to the library
         * @throws IOException if there is a problem with communication
         * @throws AgentLoadException1 if the library cannot be loaded
         * @throws AgentInitializationException1 if the command does not run properly
         */
        public void loadAgentLibrary(String lib, String command)
                        throws IOException, AgentLoadException, AgentInitializationException
        {
            try
            {
                call(vm, "loadAgentLibrary", lib, command);
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                // Change the type
                if (isSubclassOf(t, "AgentLoadException")) { throw new AgentLoadException(t); }
                if (isSubclassOf(t, "AgentInitializationException")) { throw new AgentInitializationException(t); }
                if (t instanceof IOException) { throw (IOException)t; }
                // Rethrow
                throw e;
            }
        }

        static VirtualMachine attach(String nm) throws IOException, AttachNotSupportedException
        {
            Class<?> c1 = getStaticClass();
            Object o;
            try
            {
                o = call(c1, "attach", nm);
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                if (isSubclassOf(t, "AttachNotSupportedException"))
                {
                    throw new AttachNotSupportedException(t);
                }
                if (t instanceof IOException)
                {
                    if (t.getMessage().contains("not attach to current VM"))
                    {
                        // Java 9/10 throws IOException instead of more useful AttachNotSupportedException
                        throw new AttachNotSupportedException(t);
                    }
                    throw (IOException)t;
                }
                throw e;
            }
            return new VirtualMachine(o);
        }

        private static Class<?>clsVM;
        /**
         * Find out which version of the real class we are using.
         *
         * @return
         * @throws LinkageError
         */
        private static Class<?> getStaticClass() throws LinkageError
        {
            if (clsVM == null)
            {
                clsVM = getClass("com.ibm.tools.attach.VirtualMachine", "com.sun.tools.attach.VirtualMachine");
            }
            return clsVM;
        }

        static URLClassLoader urlcl;
        static Class<?> getClass(String cn1, String cn2) throws LinkageError
            {
            Class<?> c1;
            try
            {
                c1 = Class.forName(cn1);
            }
            catch (ClassNotFoundException e)
            {
                try
                {
                    c1 = Class.forName(cn2);
                }
                catch (ClassNotFoundException e2)
                {
                    /**
                     * Oracle-based VMs don't have com.sun.tools.attach classes on the
                     * standard class path, even for JDKs.
                     * We try looking for the classes here.
                     */
                    File f = new File(System.getProperty("java.home"));
                    f = f.getParentFile();
                    if (f != null)
                    {
                        f = new File(f, "lib");
                        f = new File(f, "tools.jar");
                        if (f.canRead())
                        {
                            try
                            {
                                if (urlcl == null)
                                {
                                    urlcl = new URLClassLoader(new URL[] {f.toURI().toURL()});
                                }
                                try
                                {
                                    return urlcl.loadClass(cn2);
                                }
                                catch (ClassNotFoundException e1)
                                {
                                }
                            }
                            catch (MalformedURLException e1)
                            {
                            }
                        }
                    }
                    LinkageError l = new LinkageError();
                    l.initCause(e2);
                    throw l;
                }
            }
            return c1;
        }

        Properties getAgentProperties() throws IOException
        {
            try
            {
                return (Properties) call(vm, "getAgentProperties");
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                if (t instanceof IOException) throw (IOException)t;
                throw e;
            }
        }

        Properties getSystemProperties() throws IOException
        {
            try
            {
                return (Properties) call(vm, "getSystemProperties");
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                if (t instanceof IOException) throw (IOException)t;
                throw e;
            }
        }

        void detach() throws IOException
        {
            try
            {
                call(vm, "detach");
            }
            catch (UndeclaredThrowableException e)
            {
                Throwable t = e.getCause();
                if (t instanceof IOException) throw (IOException)t;
                throw e;
            }
        }
    }

    /**
     * Helper class to load an agent (blocking call)
     * allowing the main thread to monitor its progress
     * @author ajohnson
     *
     */
    private static final class AgentLoader extends Thread implements AgentLoader2
    {
        private final String jar;
        private final VirtualMachine vm;
        private final String command;
        private AgentLoadException e1;
        private AgentInitializationException e2;
        private IOException e3;
        private boolean fail;

        private AgentLoader(String jar, VirtualMachine vm, String command)
        {
            this.jar = jar;
            this.vm = vm;
            this.command = command;
        }

        /* (non-Javadoc)
         * @see org.eclipse.mat.ibmvm.acquire.AgentLoader2#run()
         */
        public void run() {
            try
            {
                vm.loadAgent(jar, command);
            }
            catch (AgentLoadException e2)
            {
                this.e1 = e2;
                setFailed();
            }
            catch (AgentInitializationException e)
            {
                this.e2 = e;
                setFailed();
            }
            catch (IOException e3)
            {
                this.e3 = e3;
                setFailed();
            }
        }

        /* (non-Javadoc)
         * @see org.eclipse.mat.ibmvm.acquire.AgentLoader2#failed()
         */
        public synchronized boolean failed()
        {
            return fail;
        }

        private synchronized void setFailed()
        {
            fail = true;
        }

        /* (non-Javadoc)
         * @see org.eclipse.mat.ibmvm.acquire.AgentLoader2#throwFailed(org.eclipse.mat.util.IProgressListener)
         */
        public void throwFailed(IProgressListener listener) throws SnapshotException, IOException
        {
            if (e1 != null)
            {
                listener.sendUserMessage(Severity.WARNING, Messages.getString("IBMDumpProvider.AgentLoad"), e1); //$NON-NLS-1$
                throw new SnapshotException(Messages.getString("IBMDumpProvider.AgentLoad"), e1); //$NON-NLS-1$
            }
            if (e2 != null)
            {
                listener.sendUserMessage(Severity.WARNING, Messages.getString("IBMDumpProvider.AgentInitialization"), e2); //$NON-NLS-1$
                throw new SnapshotException(Messages.getString("IBMDumpProvider.AgentInitialization"), e2); //$NON-NLS-1$
            }
            if (e3 != null)
            {
                throw e3;
            }
        }
    }

    /**
     * Find new files not ones we know about
     */
    private static final class NewFileFilter implements FileFilter
    {
        private final Collection<File> previousFiles;

        private NewFileFilter(Collection<File> previousFiles)
        {
            this.previousFiles = previousFiles;
        }

        public boolean accept(File f)
        {
            return !previousFiles.contains(f);
        }
    }

    /**
     * Indicate progress back to starting process
     * @author ajohnson
     *
     */
    private static final class StderrProgressListener implements IProgressListener
    {
        public void beginTask(String name, int totalWork)
        {}

        public void done()
        {}

        public boolean isCanceled()
        {
            return false;
        }

        public void sendUserMessage(Severity severity, String message, Throwable exception)
        {}

        public void setCanceled(boolean value)
        {}

        public void subTask(String name)
        {}

        public void worked(int work)
        {
            for (int i = 0; i < work; ++i)
            {
                System.err.print('.');
            }
        }
    }

    /**
     * sorter for files by date modified
     */
    private static final class FileComparator implements Comparator<File>, Serializable
    {
        /**
         *
         */
        private static final long serialVersionUID = -3725792252276130382L;

        public int compare(File f1, File f2)
        {
            return Long.valueOf(f1.lastModified()).compareTo(Long.valueOf(f2.lastModified()));
        }
    }

    public IBMDumpProvider()
    {
        // See if an IBM VM or an Oracle VM
        try
        {
            Class.forName("com.ibm.jvm.Dump");
        }
        catch (ClassNotFoundException e)
        {
            // Looks like no System dump is available
            defaultType = DumpType.HPROF;
        }
    }

    /**
     * Suggested name for dumps of this type
     * @return example dump name
     */
    String dumpName()
    {
        return new File("ibmdump.dmp").getAbsolutePath(); //$NON-NLS-1$
    }

    private static File agentJar;

    /**
     * Number of files generated by this dump type
     * @return the number of files, often just 1 or 2 (e.g. javacore + phd).
     */
    int files()
    {
        return 1;
    }

    /**
     * Post process a generated dump
     * @param preferredDump where the final dump should be put
     * @param compress Whether to compress/zip the dump
     * @param dumps The dump files
     * @param udir The directory where the dump files were generated
     * @param javahome The Java home directory of the process which produced the dump
     * @param listener to show progress
     * @return the result of post-processing the dump
     * @throws IOException
     * @throws InterruptedException
     * @throws SnapshotException
     */
    File jextract(File preferredDump, boolean compress, List<File>dumps, File udir, File javahome, IProgressListener listener)
                    throws IOException, InterruptedException, SnapshotException
    {
        File original = dumps.get(0);
        if (original.renameTo(preferredDump))
        {
            return preferredDump;
        }
        else
        {
            // @TODO consider java.nio.file.Files.move when we move to Java 1.7
            return original;
        }
    }

    /**
     * Average file length for a group of files.
     * @param files
     * @return
     */
    long averageFileSize(Collection<File> files)
    {
        long l = 0;
        int i = 0;
        for (File f : files)
        {
            if (f.isFile())
            {
                l += f.length();
                ++i;
            }
        }
        return l / i;
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.mat.snapshot.acquire.IHeapDumpProvider#acquireDump(org.eclipse.mat.snapshot.acquire.VmInfo, java.io.File, org.eclipse.mat.util.IProgressListener)
     */
    public File acquireDump(VmInfo info, File preferredLocation, IProgressListener listener) throws SnapshotException
    {
        IBMVmInfo vminfo = (IBMVmInfo)info;
        IBMDumpProvider helper = getDumpProvider(vminfo);
        // Delegate to the appropriate helper
        if (helper != this) return helper.acquireDump(info, preferredLocation, listener);

        listener.beginTask(Messages.getString("IBMDumpProvider.GeneratingDump"), TOTAL_WORK); //$NON-NLS-1$
        try
        {
            listener.subTask(MessageFormat.format(Messages.getString("IBMDumpProvider.AttachingToVM"), vminfo.getPidName())); //$NON-NLS-1$
            final VirtualMachine vm = VirtualMachine.attach(vminfo.getPidName());
            try
            {
                Properties props = vm.getSystemProperties();
                String javah = props.getProperty("java.home", System.getProperty("java.home")); //$NON-NLS-1$ //$NON-NLS-2$
                File javahome = new File(javah);

                // Where the dumps end up
                // %IBM_HEAPDUMPDIR%
                // %IBM_JAVACOREDIR%
                // %IBM_COREDIR%
                // pwd
                // TMPDIR
                // /tmp
                // /temp
                // user.dir
                // %LOCALAPPDATA%/VirtualStore/Program Files (x86)
                File udir;
                if (vminfo.dumpdir == null)
                {
                    udir = null;
                    if (vminfo.type == DumpType.HPROF)
                    {
                        // If we do an HPROF dump we can put it directly where it is needed
                        udir = preferredLocation.getParentFile();
                    }
                    if (udir == null)
                    {
                        String userdir = guessDumpLocation(props);
                        udir = new File(userdir);
                    }
                    // Set the directory, so even it is fails the user could adjust it
                    vminfo.dumpdir = udir;
                    //System.err.println("Setting dumpdir "+udir);
                }
                else
                {
                    udir = vminfo.dumpdir;
                }

                File f1[] = udir.listFiles();
                if (f1 == null)
                {
                    throw new FileNotFoundException(udir.getPath());
                }
                Collection<File> previous = new HashSet<File>(Arrays.asList(f1));

                long avg = averageFileSize(previous);
                //System.err.println("Average = " + avg);

                final String jar = getAgentJar().getAbsolutePath();

                listener.subTask(Messages.getString("IBMDumpProvider.StartingAgent")); //$NON-NLS-1$

                AgentLoader2 t = new AgentLoader(jar, vm, vminfo.agentCommand(new File(udir, preferredLocation.getName())));
                t.start();

                List<File> newFiles = progress(udir, previous, files(), avg, t, listener);
                if (listener.isCanceled())
                {
                    t.interrupt();
                    return null;
                }
                if (t.failed())
                {
                    t.throwFailed(listener);
                }

                listener.done();
                if (newFiles.isEmpty())
                {
                    String msg = MessageFormat.format(Messages.getString("IBMDumpProvider.UnableToFindDump"), udir.getAbsoluteFile());
                    throw new FileNotFoundException(msg);
                }
                // Consider moving to after the detach
                return jextract(preferredLocation, vminfo.compress, newFiles, udir, javahome, listener);
            }
            catch (InterruptedException e)
            {
                listener.sendUserMessage(Severity.WARNING, Messages.getString("IBMDumpProvider.Interrupted"), e); //$NON-NLS-1$
                throw new SnapshotException(Messages.getString("IBMDumpProvider.Interrupted"), e); //$NON-NLS-1$
            }
            finally {
                vm.detach();
            }
        }
        catch (IOException e)
        {
            listener.sendUserMessage(Severity.WARNING, Messages.getString("IBMDumpProvider.UnableToGenerateDump"), e); //$NON-NLS-1$
            throw new SnapshotException(Messages.getString("IBMDumpProvider.UnableToGenerateDump"), e); //$NON-NLS-1$
        }
        catch (SnapshotException e)
        {
            throw e;
        }
        catch (AttachNotSupportedException e)
        {
            info.setHeapDumpEnabled(false);
            String msg = MessageFormat.format(Messages.getString("IBMDumpProvider.UnsuitableVM"), info.toString());
            listener.sendUserMessage(Severity.WARNING, msg, e); //$NON-NLS-1$
            throw new SnapshotException(msg, e); //$NON-NLS-1$
        }

    }

    /**
     * Update the progress bar for created files
     * @param udir directory where files are created
     * @param previous
     * @param nfiles
     * @param loader Thread which has loaded the agent jar
     * @throws FileNotFoundException
     */
    private List<File> progress(File udir, Collection<File> previous, int nfiles, long avg, AgentLoader2 loader, IProgressListener listener)
                    throws InterruptedException, FileNotFoundException
    {
        listener.subTask(Messages.getString("IBMDumpProvider.WaitingForDumpFiles")); //$NON-NLS-1$
        List<File> newFiles = new ArrayList<File>();
        // Wait up to 30 seconds for a file to be created and written to
        long l = 0;
        int worked = 0;
        long start = System.currentTimeMillis(), t;
        for (int i = 0; (l = fileLengths(udir, previous, newFiles, nfiles)) == 0
            && i < CREATE_COUNT && (t = System.currentTimeMillis()) < start + CREATE_COUNT*SLEEP_TIMEOUT; ++i)
        {
            Thread.sleep(SLEEP_TIMEOUT);
            if (listener.isCanceled() || loader.failed())
                return null;
            int towork = (int)Math.min(((t - start) / SLEEP_TIMEOUT), CREATE_COUNT);
            listener.worked(towork - worked);
            worked = towork;
        }

        listener.worked(CREATE_COUNT - worked);
        worked = CREATE_COUNT;

        // Wait for FINISHED_TIMEOUT seconds after file length stops changing
        long l0 = l - 1;
        int iFile = 0;
        start = System.currentTimeMillis();
        for (int i = 0, j = 0; ((l = fileLengths(udir, previous, newFiles, nfiles)) != l0
                        || j++ < FINISHED_COUNT || newFiles.size() > iFile)
                        && i < GROW_COUNT
                        && (t = System.currentTimeMillis()) < start + GROW_COUNT*SLEEP_TIMEOUT; ++i)
        {
            while (iFile < newFiles.size())
            {
                listener.subTask(MessageFormat.format(Messages.getString("IBMDumpProvider.WritingFile"), newFiles.get(iFile++))); //$NON-NLS-1$
            }
            if (l0 != l)
            {
                j = 0;
                int towork = (int) (l * GROWING_COUNT / avg);
                listener.worked(towork - worked);
                worked = towork;
                l0 = l;
            }
            Thread.sleep(SLEEP_TIMEOUT);
            if (listener.isCanceled() || loader.failed())
                return null;
            listener.worked(1);
        }
        // Remove files which no longer exist
        for (Iterator<File>it = newFiles.iterator(); it.hasNext();)
        {
            File f = it.next();
            if (!f.exists())
                it.remove();
        }
        return newFiles;
    }

    private static synchronized File getAgentJar() throws IOException
    {
        if (agentJar == null || !agentJar.canRead())
        {
            agentJar = makeAgentJar();
        }
        return agentJar;
    }

    private static File makeAgentJar() throws IOException, FileNotFoundException
    {
        String jarname = "org.eclipse.mat.ibmdumps"; //$NON-NLS-1$
        String agents[] = { "org.eclipse.mat.ibmvm.agent.DumpAgent" }; //$NON-NLS-1$
        Class<?> cls[] = new Class<?>[0];
        return makeJar(jarname, "Agent-class: ", agents, cls); //$NON-NLS-1$
    }

    /**
     * Find the new files in a directory
     *
     * @param udir
     *            The directory
     * @param previousFiles
     *            File that we already know exist in the directory
     * @param newFiles
     *            newly discovered files, in discovery/modification order
     * @return a list of new files in the directory
     * @throws FileNotFoundException
     */
    List<File> files(File udir, final Collection<File> previousFiles, List<File> newFiles) throws FileNotFoundException
    {
        File f2[] = udir.listFiles(new NewFileFilter(previousFiles));
        if (f2 == null)
        {
            throw new FileNotFoundException(udir.getPath());
        }
        List<File> new2 = Arrays.asList(f2);
        // Sort the new files in order of modification
        Collections.sort(new2, new FileComparator());
        previousFiles.addAll(new2);
        newFiles.addAll(new2);
        return newFiles;
    }

    long fileLengths(File udir, Collection<File> previous, List<File> newFiles, int maxFiles) throws FileNotFoundException
    {
        Collection<File> nw = files(udir, previous, newFiles);
        long l = 0;
        int i = 0;
        for (File f : nw)
        {
            if (!f.exists())
            {
                // File has disappeared (e.g. on Linux renamed from core to core.????)
                // Just skip it and don't include in the count
                continue;
            }
            if (++i > maxFiles)
                break;
            l += f.length();
        }
        return l;
    }

    /**
     * @see org.eclipse.mat.snapshot.acquire.IHeapDumpProvider#getAvailableVMs(org.eclipse.mat.util.IProgressListener)
     */
    public List<IBMVmInfo> getAvailableVMs(IProgressListener listener)
    {
        try
        {
            return getAvailableVMs1(listener);
        }
        catch (LinkageError e)
        {
            return null;
        }
    }

    /**
     * List available VMs.
     * work done calculated as below:
     * T = 10
     * N = 100
     * X->1..100
     *
     * Step p = x*T/N - (x-1)*T/N
     *
     * @param listener
     * @return a list of VMs
     */
    private List<IBMVmInfo> getAvailableVMs1(IProgressListener listener)
    {
        int totalwork = 24;
        int provwork = 4;
        listener.beginTask(Messages.getString("IBMDumpProvider.ListingIBMVMs"), totalwork); //$NON-NLS-1$
        int y = 0;
        int vmcount = VirtualMachine.list().size();
        int x = 0;
        List<IBMVmInfo> jvms = new ArrayList<IBMVmInfo>();
        List<AttachProvider> provs = AttachProvider.providers();
        int provcount = provs.size();
        for (AttachProvider prov : provs)
        {
            listener.subTask(MessageFormat.format(Messages.getString("IBMDumpProvider.ListingFirst"), prov.name())); //$NON-NLS-1$
            List<VirtualMachineDescriptor> list = prov.listVirtualMachines();
            y++;
            int workp = y * provwork / provcount - (y - 1) * provwork / provcount;
            listener.worked(workp);
            listener.subTask(MessageFormat.format(Messages.getString("IBMDumpProvider.ListingDetails"), prov.name())); //$NON-NLS-1$
            for (VirtualMachineDescriptor vmd : list)
            {
                IBMVmInfo ifo = getVmInfo(vmd);
                jvms.add(ifo);
                ++x;
                int workv = x * (totalwork - provwork) / vmcount - (x - 1) * (totalwork - provwork) / vmcount;
                listener.worked(workv);
                if (listener.isCanceled())
                {
                    // If the user cancelled then perhaps the attach is hanging
                    listAttach = false;
                    break;
                }
            }
        }
        listener.done();
        return jvms;
    }

    private IBMVmInfo getVmInfo(VirtualMachineDescriptor vmd)
    {
        boolean usable = true;
        String unusableCause = "";
        String dir = null;
        // See if the VM is usable to get dumps
        String displayName = vmd.displayName();
        if ((vmd.id().equals(displayName) || "".equals(displayName)) && listAttach)
        {
            // Insufficient details of running VM, so attach for more information
            try
            {
                // Hope that this is not too intrusive to the target
                VirtualMachine vm = vmd.provider().attachVirtualMachine(vmd);
                try
                {
                    Properties p = vm.getSystemProperties();
                    dir = p.getProperty("user.dir");
                    // Get something which might identify the running VM to
                    // the user
                    displayName = p.getProperty("java.class.path");
                    if (displayName == null || displayName.equals(""))
                    {
                        displayName = dir;
                    }
                    dir = guessDumpLocation(p);
                }
                finally
                {
                    try
                    {
                        vm.detach();
                    }
                    catch (NullPointerException e)
                    {
                        // Ignore from IBM Java 9
                    }
                }
                // See if loading an agent would fail
                // Java 5 SR10 and SR11 don't have a loadAgent method, so find
                // out now
                try
                {
                    vm.loadAgent((String)null, (String)null);
                }
                catch (AgentLoadException e)
                {
                }
                catch (AgentInitializationException e)
                {
                }
                catch (LinkageError e)
                {
                    usable = false;
                    unusableCause = e.getLocalizedMessage();
                }
                catch (NullPointerException e)
                {
                    // Ignore
                }
                catch (IOException e)
                {
                    // Ignore, expect an IOException if the method exists as the VM is detached
                }
            }
            catch (IOException e)
            {
                usable = false;
                unusableCause = e.getLocalizedMessage();
            }
            catch (AttachNotSupportedException e)
            {
                usable = false;
                unusableCause = e.getLocalizedMessage();
            }
        }

        // Create VMinfo to generate heap dumps

        String desc = MessageFormat.format(Messages.getString("IBMDumpProvider.VMDescription"), vmd.provider().name(), vmd.provider().type(), displayName); //$NON-NLS-1$
        if (!usable)
        {
            desc = unusableCause + " : " + desc;
        }
        IBMVmInfo ifo = new IBMVmInfo(vmd.id(), desc, usable, null, this);
        if (vmd.provider().name().equals("sun"))
        {
            ifo.type = DumpType.HPROF;
            // No need for a dump directory - HPROF can dump directly to the required location
            dir = null;
        }
        else
        {
            ifo.type = defaultType;
        }
        ifo.live = defaultLive;
        ifo.compress = defaultCompress;
        if (dir != null)
            ifo.dumpdir = new File(dir);
        ifo.setHeapDumpEnabled(usable);
        return ifo;
    }

    private String guessDumpLocation(Properties props)
    {
        String dir = props.getProperty("user.dir", System.getProperty("user.dir")); //$NON-NLS-1$ //$NON-NLS-2$
        // If there is a system trace file perhaps the dumps also do there
        String tracefilename = props.getProperty("system.trace.file"); //$NON-NLS-1$
        if (tracefilename != null)
        {
            File tracefile = (new File(tracefilename));
            File tdir = tracefile.getParentFile();
            if (tdir != null)
            {
                File tdira = tdir.getAbsoluteFile();
                if (tdir.equals(tdira))
                {
                    // Must be an absolute path, because otherwise could be different
                    // when examined from this process
                    dir = tdir.getPath();
                }
            }
        }
        return dir;
    }

    /**
     * Lists VMs or acquires a dump.
     * Used when attach API not usable from the MAT process.
     *
     * @param s <ul><li>[0] dump type (HEAP=heap+java,SYSTEM=system,JAVA=java)</li>
     *        <li>[1] VM id = PID</li>
     *        <li>[2] true/false live objects only in dump</li>
     *        <li>[3] true/false compress dump</li>
     *        <li>[4] dump name</li>
     *        <li>[5] dump directory (optional)</li>
     *        </ul>
     *        List VMs
     *        <ul>
     *        <li>true - attach to VM to get more details</li>
     *        </ul>
     * Output<ul>
     * <li>dump filename</li>
     * <li>or list of all processes (if argument list is empty)
     * <pre>PID;proposed file name;directory;enable dump;description</pre></li>
     * </ul>
     */
    public static void main(String s[]) throws Exception
    {
        IBMDumpProvider prov = new IBMDumpProvider();
        if (s.length < 5 && s.length > 0)
        {
            prov.listAttach = Boolean.parseBoolean(s[0]);
        }
        IProgressListener ii = new StderrProgressListener();
        List<IBMVmInfo> vms = prov.getAvailableVMs1(ii);
        for (VmInfo info : vms)
        {
            IBMVmInfo vminfo = (IBMVmInfo)info;
            String vm = vminfo.getPidName();
            String dir = vminfo.dumpdir != null ? vminfo.dumpdir.getAbsolutePath() : "";
            String proposedFile = info.getProposedFileName();
            // Let the file be determined later
            proposedFile = "";
            String vm2 = vm + INFO_SEPARATOR + info.isHeapDumpEnabled() + INFO_SEPARATOR + vminfo.type + INFO_SEPARATOR + proposedFile + INFO_SEPARATOR + dir + INFO_SEPARATOR  + info.getDescription();
            if (s.length < 5)
            {
                System.out.println(vm2);
            }
            else
            {
                if (vm.equals(s[1]))
                {
                    DumpType tp = DumpType.valueOf(s[0]);
                    vminfo.type = tp;
                    vminfo.live = Boolean.parseBoolean(s[2]);
                    vminfo.compress = Boolean.parseBoolean(s[3]);
                    if (s.length > 5)
                    {
                        vminfo.dumpdir = new File(s[5]);
                    }
                    File f2 = vminfo.getHeapDumpProvider().acquireDump(info, new File(s[4]), ii);
                    System.out.println(f2.getAbsolutePath());
                    return;
                }
            }
        }
        if (s.length > 1)
        {
            throw new IllegalArgumentException(MessageFormat.format(Messages.getString("IBMDumpProvider.NoVMFound"), s[1])); //$NON-NLS-1$
        }
    }

    IBMDumpProvider getDumpProvider(IBMVmInfo info)
    {
        if (getClass() != IBMDumpProvider.class)
           return this;
        else if (info.type == DumpType.SYSTEM)
            return new IBMSystemDumpProvider();
        else if (info.type == DumpType.HEAP)
            return new IBMHeapDumpProvider();
        else if (info.type == DumpType.JAVA)
            return new IBMJavaDumpProvider();
        else if (info.type == DumpType.HPROF)
            return new HprofDumpProvider();
        return this;
    }

    /**
     * Update date and time stamps in suggested file name from actual file
     * @param preferredDump
     * @param actual
     * @return
     */
    File mergeFileNames(File preferredDump, File actual)
    {
        String fn1 = preferredDump.getName();
        String fn1a = fn1.replaceAll("\\d", "#"); //$NON-NLS-1$//$NON-NLS-2$
        String fn2 = actual.getName();
        String fn2a = fn2.replaceAll("\\d", "#"); //$NON-NLS-1$//$NON-NLS-2$
        fn2a = fn2a.substring(0, fn2a.lastIndexOf('#') + 1);
        int fi = fn1a.indexOf(fn2a);
        File ret;
        if (fi >= 0)
        {
            String newfn = fn1.substring(0, fi) + fn2.substring(0, fn2a.length()) + fn1.substring(fi + fn2a.length());
            ret = new File(preferredDump.getParentFile(), newfn);
        }
        else
        {
            ret = preferredDump;
        }
        return ret;
    }
}
