/*******************************************************************************
 * Copyright (c) 2006 IBM Corporation and others.
 * 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 API and implementation
 *     Matt Chapman - initial version
 *     Helen Hawkins - updated for new ajde interface (bug 148190) 
 *******************************************************************************/
package org.eclipse.ajdt.internal.core.ajde;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import org.aspectj.ajde.core.IOutputLocationManager;
import org.eclipse.ajdt.core.AJLog;
import org.eclipse.ajdt.core.AspectJCorePreferences;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.builder.State;
import org.eclipse.jdt.internal.core.builder.StringSet;
import org.eclipse.jdt.internal.core.util.Util;

/**
 * IOutputLocationManager implementation which uses the methods on IJavaProject
 * to work out where the output should be sent.
 * 
 * Important note about paths:
 * Use Path.toOSString when describing a file on the filesystem
 * Use Path.toPortableString when describing a resource in Eclipse's workspace.
 */
public class CoreOutputLocationManager implements IOutputLocationManager {

    /**
     * 
     * @author Andrew Eisenberg
     * @created Apr 9, 2009
     * use this to ensure that the longest strings are looked at first
     * 
     * so, if src and src2 are both source folders, src2 will be
     * examined first
     */
    static class StringLengthComparator implements Comparator<String> {
        public int compare(String s1, String s2) {
            if (s1 == null) {
                if (s2 == null) {
                    return 0;
                }
                return -1;
            }
            if (s2 == null) {
                return 1;
            }
            int len1 = s1.length();
            int len2 = s2.length();
            if (len1 > len2) {  // a larger string should come first
                return -1;
            } else if (len1 == len2) {
                // then compare by text:
                return s1.compareTo(s2);
            } else {
                return 1;
            }
        }
        
    }
    
    private static final StringLengthComparator comparator = new StringLengthComparator();
    
	private final IProject project;
	private final IJavaProject jProject;

	// if there is more than one output directory then the default output
	// location to use is recorded in the 'defaultOutput' field
	private File defaultOutput;
	
	private Map<String, File> srcFolderToOutput = new TreeMap<String, File>(comparator);
	
	private Map<File, IProject> binFolderToProject;
	
	// maps files in the file system to IFolders in the workspace
	// this keeps track of output locations
    private final Map<String, IContainer> fileSystemPathToIContainer = new TreeMap<String, IContainer>(comparator);

	private List<File> allOutputFolders = new ArrayList<File>();
	
	// maps file system location to a path within the eclipse workspace
	// needs to take into account linked sources, where the actual
	// file system location may be different from the workspace location
	private Map<String, String> allSourceFolders;
	
	private boolean outputIsRoot;
	// if there is only one output directory then this is recorded in the
	// 'commonOutputDir' field.
	private File commonOutputDir;
    private IWorkspaceRoot workspaceRoot;
    
    // Gather all of the files that are touched by this compilation
    // and use it to determine which files need to have their 
    // Relationship maps updated.
    private Set<File> compiledSourceFiles;

    private FileURICache fileCache;

	public CoreOutputLocationManager(IProject project, FileURICache fileCache) {
		this.project = project;
        this.fileCache = fileCache;
		this.workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		jProject = JavaCore.create(project);
        initSourceFolders();
		if (!isUsingSeparateOutputFolders(jProject)) {
			// using the same output directory therefore record this one
			setCommonOutputDir();
			allOutputFolders.add(commonOutputDir);

			if (commonOutputDir != null) {
    			try {
    			    if (outputIsRoot) {
                        fileSystemPathToIContainer.put(commonOutputDir.getAbsolutePath(), 
                                project);
    			    } else {
                        fileSystemPathToIContainer.put(commonOutputDir.getAbsolutePath(), 
                                workspaceRoot.getFolder(jProject.getOutputLocation()));
    			    }
                } catch (JavaModelException e) {
                }
			}
		} else {
			// need to record all possible output directories
			init();
		}
		
	}
	
	public void buildStarting() {
	    compiledSourceFiles = new HashSet<File>();
	}
	
	public void buildComplete() {
	    compiledSourceFiles = null;
	}
	
	/**
	 * initialize the source folder locations only
	 */
	private void initSourceFolders() {
	    allSourceFolders = new TreeMap<String, String>(comparator);
	    try {
            IClasspathEntry[] cpe = jProject.getRawClasspath();
            for (int i = 0; i < cpe.length; i++) {
                if (cpe[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    IPath path = cpe[i].getPath();
                    IPath rawPath;
                    path = path.removeFirstSegments(1).makeRelative();
                    if (path.segmentCount() > 0) {
                        IFolder folder = project.getFolder(path);
                        rawPath = folder.getLocation();
                    } else {
                        rawPath = project.getLocation();
                    }
                    allSourceFolders.put(rawPath.toOSString(), path.toPortableString());
                }
            }
        } catch (JavaModelException e) {
        }
	}
	
	/**
	 * Calculate all the output locations
	 */
	private void init() {
		outputIsRoot = false;
		String inpathOutFolderString = getInpathOutputFolder();
		boolean isUsingNonDefaultInpathOutfolder = inpathOutFolderString != null;

		try {
			IPath outputLocationPath = jProject.getOutputLocation();
            defaultOutput = workspacePathToFile(outputLocationPath);
			allOutputFolders.add(defaultOutput);
			
			
			fileSystemPathToIContainer.put(defaultOutput.getAbsolutePath(), 
			        project.getFullPath().equals(outputLocationPath) 
			                ? (IContainer) project
			                : (IContainer) workspaceRoot.getFolder(outputLocationPath));

			
			IClasspathEntry[] cpe = jProject.getRawClasspath();
			
			
			// store separate output folders in map
			for (int i = 0; i < cpe.length; i++) {
                if (cpe[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                    IPath output = cpe[i].getOutputLocation();
                    if (output != null) {
                        IPath path = cpe[i].getPath();
    
                        String srcFolder = path.removeFirstSegments(1).toPortableString();
                        if (path.segmentCount() == 1) { // output folder is project
                            srcFolder = path.toPortableString();
                        }
                        File out = workspacePathToFile(output);
                        srcFolderToOutput.put(srcFolder, out);
                        if (!allOutputFolders.contains(out)) {
                            allOutputFolders.add(out);
    
                            fileSystemPathToIContainer.put(out.getAbsolutePath(), 
                                    workspaceRoot.getFolder(output));
                        }
                        if (outputIsRoot) {
                            // bug 153682: if the project is the source folder
                            // then this output folder will always apply
                            defaultOutput = out;
                        }
                    }
                }
			}
			
            // check to see if on inpath and need a special out folder for it.
            if (isUsingNonDefaultInpathOutfolder) {
                // first add the inpath out folder to the list of out folders
                IPath inpathOutFolderPath = new Path(inpathOutFolderString);
                IFolder inpathOutFolder = workspaceRoot.getFolder(inpathOutFolderPath);
                File out = inpathOutFolder.getLocation().toFile();
                fileSystemPathToIContainer.put(out.getAbsolutePath(), 
                        workspaceRoot.getFolder(inpathOutFolderPath));
                
                // now map everything coming from the in path to this out folder
                for (int i = 0; i < cpe.length; i++) {
                    if (AspectJCorePreferences.isOnInpath(cpe[i])) {
                        // now must resolve the entry so that all jars contained in it 
                        // are mapped.
                        List<IClasspathEntry> containerEntries = AspectJCorePreferences.resolveClasspath(cpe[i], project);
                        for (IClasspathEntry containerEntry : containerEntries) {
                            IPath path = containerEntry.getPath();
                            File f = workspacePathToFile(path);
                            if (f != null && f.exists()) {
                                // use full path
                                String srcFolder = new Path(f.getPath()).toPortableString();
                                srcFolderToOutput.put(srcFolder,out);
                            } else {
                                // outfolder does not exist
                                // probably because Project has been renamed
                                // and inpath output location has not been updated.
                                // this is handled with a message to the user
                            }
                        }
                    }
                }
			}
		} catch (JavaModelException e) {
		}
	}
	
	private boolean isComputingXmlFile() {
		StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
		int max = stacktrace.length;
		if (max > 6) max = 6;
		for (int i=(max-1);i>0;i--) {
			String s = stacktrace[i].toString();
			// org.aspectj.ajdt.internal.core.builder.AjBuildManager.writeOutxmlFile(AjBuildManager.java:659) probably at i==4
			if (s.startsWith("org.aspectj.ajdt.internal.core.builder.AjBuildManager.writeOutxmlFile")) {
				return true;
			}
		}	
		return false;
	}
	
	public File getOutputLocationForClass(File compilationUnit) {
	    // remember that this file has been asked for
	    // presumably it is being recompiled
	    if (Util.isJavaLikeFileName(compilationUnit.getName()) && !isComputingXmlFile()) {     
	    	if (compiledSourceFiles == null) {
	    		// pr540403
	    		AJLog.log(AJLog.BUILDER,"Unexpectedly buildStarted() has not been called yet, unable to record: "+compilationUnit.getName());
	    	} else {
	    		compiledSourceFiles.add(compilationUnit);
	    	}
	    }
	    
		return getOutputLocationForResource(compilationUnit);
	}

	public File getOutputLocationForResource(File resource) {
		if (!isUsingSeparateOutputFolders(jProject)) {
			return commonOutputDir;
		}
		if (resource == null || resource.toString() == null) {
			return defaultOutput;
		}
		
		// due to linked files, there may be multiple IResource relating to a single File
		IResource[] resources;
		IFile[] files = fileCache.findFilesForURI(resource.toURI());
		if (files != null && files.length > 0) {
		    resources = new IResource[files.length];
		    for (int i = 0; i < files.length; i++) {
                resources[i] = files[i];
            }
		} else {
	        IContainer[] containers = fileCache.findContainersForURI(resource.toURI());
	        if (containers != null && containers.length > 0) {
	            resources = new IResource[containers.length];
	            for (int i = 0; i < containers.length; i++) {
	                resources[i] = containers[i];
	            }
	        } else {
	            resources = null;
	        }
		}
		
		String pathStr = null;
		if (resources != null && resources.length > 0) {
		    // check if there is another version of the file
		    // that is linked to this project
		    // since the IResources are returned in an 
		    // arbitrary order, doesn't matter which one we choose
		    IProject project = jProject.getProject();
		    for (int i = 0; i < resources.length; i++) {
                if (resources[i].getProject().equals(project)) {
                    pathStr = resources[i].getFullPath().removeFirstSegments(1).toPortableString();
                    break;
                }
            }
		    if (pathStr == null) {
		        // this is from a location outside of the current project,
		        // use full path
		        pathStr = resources[0].getLocation().toPortableString();
		    }
		}
		
		if (pathStr == null) {
		    // if still null at this point, then assume that we have a fully qualified path
		    // coming from the inpath going to the inpath out folder
		    pathStr = new Path(resource.getPath()).toPortableString();
		}

		for (String src : srcFolderToOutput.keySet()) {
            if (pathStr.startsWith(src)) {
                File out = srcFolderToOutput.get(src);
                return out;
            }
	    }
		
		// couldn't find anything
		return defaultOutput;
	}

	/**
	 * @return true if there is more than one output directory being used by
	 *         this project and false otherwise
	 */
	private boolean isUsingSeparateOutputFolders(IJavaProject jp) {
		if (getInpathOutputFolder() != null) {
		    return true;
		}
	    try {
			IClasspathEntry[] cpe = jp.getRawClasspath();
			for (int i = 0; i < cpe.length; i++) {
				if (cpe[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
					if (cpe[i].getOutputLocation() != null) {
						return true;
					}
				}
			}
		} catch (JavaModelException e) {
		}
		return false;
	}

	/**
	 * Record the 'common output directory', namely the one where all the output
	 * goes
	 */
	private void setCommonOutputDir() {
		IJavaProject jProject = JavaCore.create(project);
		IPath workspaceRelativeOutputPath;
		try {
			workspaceRelativeOutputPath = jProject.getOutputLocation();
		} catch (JavaModelException e) {
			commonOutputDir = project.getLocation().toFile();
            outputIsRoot = true;
			return;
		}
		if (workspaceRelativeOutputPath.segmentCount() == 1) { 
			commonOutputDir = jProject.getResource().getLocation().toFile();
			outputIsRoot = true;
			return;
		}
		IFolder out = ResourcesPlugin.getWorkspace().getRoot().getFolder(workspaceRelativeOutputPath);
		commonOutputDir = out.getLocation().toFile();
	}

	private File workspacePathToFile(IPath path) {
		if (path.segmentCount() == 1) {
			// bug 153682: getFolder fails when the path is a project
			IResource res = workspaceRoot.findMember(path);
			outputIsRoot = true;
			return res.getLocation().toFile();
		}
		
		IPath outPath;
		IResource out;
		String fileExtension = path.getFileExtension();
        if (fileExtension != null) {
            // assume a file
		    out = workspaceRoot.getFile(path);
		} else {
		    out = workspaceRoot.getFolder(path);
		}
		if (out.getProject().exists()) {
		    outPath = out.getLocation();
		} else {
		    // maybe this is a fully qualified path
		    outPath = path;
		}
		
		if (outPath != null) {
			return outPath.toFile();
		} else {
			return null;
		}
	}
	

	/**
	 * return all output directories used by this project
	 */
	public List<File> getAllOutputLocations() {
		return allOutputFolders;
	}

	public String getInpathOutputFolder() {
		String inpathOutFolder = AspectJCorePreferences.getProjectInpathOutFolder(project);
		// assume that the folder is valid...
		// null means that the default out folder is used
		return inpathOutFolder;
	}

	
	/**
     * Called when build is completed.  Respond with all source files compiled
     * for this build
     * @return all source files compiled for this build
     */
    public File[] getCompiledSourceFiles() {
        return compiledSourceFiles == null ? new File[0] : compiledSourceFiles.toArray(new File[compiledSourceFiles.size()]);
    }


	/**
	 * If there's only one output directory return this one, otherwise return
	 * the one marked as default
	 */
	public File getDefaultOutputLocation() {
		if (!isUsingSeparateOutputFolders(jProject)) {
			return commonOutputDir;
		} else {
			return defaultOutput;
		}
	}

	public String getSourceFolderForFile(File sourceFile) {
		String sourceFilePath = sourceFile.getAbsolutePath();
		for (Entry<String, String> sourceFolderMapping : allSourceFolders.entrySet()) {
			if (sourceFilePath.startsWith(sourceFolderMapping.getKey())) {
				return sourceFolderMapping.getValue();
			}
		}
		
		// might be a linked folder in a source folder
		IFile[] files = fileCache.findFilesForURI(sourceFile.toURI());
		try {
            IPackageFragmentRoot[] roots = jProject.getPackageFragmentRoots();
            for (IPackageFragmentRoot root : roots) {
                if (!root.isReadOnly()) {
                    IContainer container = (IContainer) root.getResource();
            	    for (IFile file : files) {
                        if (container.getFullPath().isPrefixOf(file.getFullPath())) {
                            return allSourceFolders.get(container.getLocation().toOSString());
                        }
                    }
                }
            }
        } catch (JavaModelException e) {
        }
		
		
		return null;
	}

	public void reportFileRemove(String outFileStr, int fileType) {
	    for (Entry<String, IContainer> entry : fileSystemPathToIContainer.entrySet()) {
            String outFolderStr = entry.getKey();
            if (outFileStr.startsWith(outFolderStr)) {
                IContainer outFolder = entry.getValue();
                IFile outFile = outFolder.getFile(new Path(outFileStr.substring(outFolderStr.length())));
                try {
                    outFile.refreshLocal(IResource.DEPTH_ZERO, null);
                    return;
                } catch (CoreException e) {
                }
            }
        }

	}


	public Map<File,String> getInpathMap() {
		return Collections.emptyMap();
	}


	/**
	 * This method must do two things.  First, it performs a refreshLocal on
	 * the newly changed file.  Then it marks the file and all of its parent
	 * folders as derived (up to, but not including the output folder itself).
	 * Folders are marked as derived only if the output folder is not the same
	 * as the source folder.
	 */
	public void reportFileWrite(String outFileStr, int fileType) {
	    try {
	        outer:
	        for (Entry<String, IContainer> entry : fileSystemPathToIContainer.entrySet()) {
	            String outFolderStr = entry.getKey();
	            if (outFileStr.startsWith(outFolderStr)) {
	                IContainer outFolder = entry.getValue();
	                IFile outFile = outFolder.getFile(new Path(outFileStr.substring(outFolderStr.length())));
	                
	                outFile.refreshLocal(IResource.DEPTH_ZERO, null);
	                
	                if (outFile.exists()) {
	                    
	                    // if this is a resource whose source folder and out folder are the same,
	                    // do not mark as derived
	                    boolean outputIsSourceFolder = isOutFolderASourceFolder(outFolder);
	                    if (! isResourceInSourceFolder(outFile, outputIsSourceFolder)) {
	                        outFile.setDerived(true, null);
	                    }
	                    
	                    // only do this if output is not a source folder
	                    if (!outputIsSourceFolder) {
	                        IContainer parent = outFile.getParent();
	                        inner:
	                        while (!parent.equals(outFolder) ) {
	                            if (!parent.isDerived()) {
    	                            parent.setDerived(true, null);
	                            } else {
	                                // no need to continnue
	                                // assume that all folders are derived all the way up
	                                break inner;
	                            }
	                            parent = parent.getParent();
	                            if (parent == null) {
	                                // shouldn't happen
	                                break inner;
	                            }
	                        }
	                    }
	                    break outer;
	                }
	            }
	            
	        }
	    } catch (CoreException e) {
	    }
	}

    private boolean isResourceInSourceFolder(IFile outFile,
            boolean outputIsSourceFolder) {
        return !(outFile.getFileExtension() != null && outFile.getFileExtension().equals("class"))
                && outputIsSourceFolder;
    }
    
    private boolean isOutFolderASourceFolder(IContainer outFolder) {
        return outputIsRoot || srcFolderToOutput.containsKey(outFolder.getFullPath().removeFirstSegments(1).makeRelative().toPortableString());
    }
	
	/**
	 * Return the Java project that has outputFolder as an output location, or null if it is
	 * not recognized.
	 * 
	 * This method can return null if outputFolder is not found 
	 * in any declaring project
	 * 
	 */
	protected IProject findDeclaringProject(File outputFolder) {
	    if (binFolderToProject == null) {
	        initDeclaringProjectsMap();
	    }
	    return binFolderToProject.get(outputFolder);
	}

	
	/**
	 * the field binFolderToProject must be refreshed before each build
	 * because we are not sure if any bin folders in downstream projects 
	 * have changed.
	 * 
	 * See bug 270335
	 */
	protected void zapBinFolderToProjectMap() {
	    binFolderToProject = null;
	}

	/**
	 * Initialize the binFolderToProject map so that the map contains 
	 * java.io.File -> IProject  where the file is an output location
	 * and the project is where this output location is defined
	 */
	private void initDeclaringProjectsMap() {
	    
	    AJLog.logStart("OutputLocationManager: binary folder to declaring project map creation: " + project);
	    binFolderToProject = new HashMap<File, IProject>();
	    IJavaProject jp = jProject;
        try {
            mapProject(jp);
        } catch (JavaModelException e) {
        }
        AJLog.logEnd(AJLog.BUILDER_CLASSPATH, "OutputLocationManager: binary folder to declaring project map creation: " + project);
    }

    private void mapProject(IJavaProject jp) throws JavaModelException {
        IClasspathEntry[] cpes = jp.getRawClasspath();
        for (int i = 0; i < cpes.length; i++) {
            if (cpes[i].isExported() || 
                    cpes[i].getEntryKind() == IClasspathEntry.CPE_SOURCE || 
                    jp == jProject) {
                handleClassPathEntry(jp, cpes[i]);
            }
        }
    }

    private void handleClassPathEntry(IJavaProject jp, IClasspathEntry cpe) throws JavaModelException {
        switch (cpe.getEntryKind()) {
            case IClasspathEntry.CPE_CONTAINER:
                IClasspathContainer container = 
                    JavaCore.getClasspathContainer(cpe.getPath(), jp);
                if (container != null && container.getKind() != IClasspathContainer.K_DEFAULT_SYSTEM) {
                    IClasspathEntry[] cpes = container.getClasspathEntries();
                    for (int i = 0; i < cpes.length; i++) {
                        handleClassPathEntry(jp, cpes[i]);
                    }
                }
                break;
            case IClasspathEntry.CPE_LIBRARY:
                File libFile = pathToFile(cpe.getPath());
                if (libFile.isDirectory()) {  // ignore jar files
                    if (libFile != null && !binFolderToProject.containsKey(libFile)) {
                        binFolderToProject.put(libFile, jp.getProject());
                    }
                }
                break;
            case IClasspathEntry.CPE_PROJECT:
                IJavaProject jpClasspath = pathToProject(cpe.getPath());
                if (jpClasspath != null) {
                    mapProject(jpClasspath);
                }
                break;
                
            case IClasspathEntry.CPE_SOURCE:
                File outFile = pathToFile(cpe.getOutputLocation() == null ? jp.getOutputLocation() : cpe.getOutputLocation());
                if (outFile != null && ! binFolderToProject.containsKey(outFile)) {
                    binFolderToProject.put(outFile, jp.getProject());
                }
                break;
            case IClasspathEntry.CPE_VARIABLE:
                IClasspathEntry cpeResolved = JavaCore.getResolvedClasspathEntry(cpe);
                if (cpeResolved != null) {
                    handleClassPathEntry(jp, cpeResolved);
                }
                break;
        }
    }
    
    private IJavaProject pathToProject(IPath path) {
        if (path != null && path.segmentCount() > 0) {
            IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segments()[0]);
            return JavaCore.create(p);
        } else {
            return null;
        }
    }

    private File pathToFile(IPath path) {
        // Bug 279497 if path is only one segment, then assume it is a project
        
        IPath locPath = path.segmentCount() > 1 ? 
                ResourcesPlugin.getWorkspace().getRoot().getFolder(path).getLocation() :
                ResourcesPlugin.getWorkspace().getRoot().getProject(path.makeRelative().toOSString()).getLocation();
        File f;
        if (locPath != null) {
            f = locPath.toFile();
        } else {
            f = path.toFile();
        }
        return f;
    }

    /**
	 * Aim of this callback from the compiler is to ask Eclipse if it knows which project has the 
	 * supplied directory as an output folder, and if that can be determined then look at the 
	 * last structural build time of that project and any structurally changed types since that
	 * build time.  If it doesn't look like anything has changed since the supplied buildtime then
	 * we assume that means nothing changed in the directory and so do not need to check the time
	 * stamp of each file within it.
	 * 
	 * This method does nothing more than a rudimentary analysis - if there are changes then it does
	 * not currently attempt to determine if they are interesting (ie. whether they are changes to 
	 * types that the compiler asking the question depends upon).
	 */
	public int discoverChangesSince(File dir, long buildtime) {
		IProject project = findDeclaringProject(dir);
		try {
			if (project!=null) {
	            Object s = JavaModelManager.getJavaModelManager().getLastBuiltState(project, null);
	            if (s != null && s instanceof State) {
	                State state = (State) s;
	                long dependeeTime = getLastStructuralBuildTime(state);
	                if (dependeeTime < buildtime) {
	                	StringSet changes = getStructurallyChangedTypes(state);
	                	// this test isn't quite right... but it basically works
	                    if (changes==null || changes.elementSize==0) {
	                    	return 1; // no changes at all (doesnt determine whether they are of interest)
	                    }
	                }
	            }
			}
		} catch (Exception e) {
		}
		return 0; // DONTKNOW - this will cause the caller to do the .class modtime tests
	}

	
    private static long getLastStructuralBuildTime(State state)
            throws Exception {
        if (lastStructuralBuildTimeField == null) {
            lastStructuralBuildTimeField = State.class.getDeclaredField("lastStructuralBuildTime");
            lastStructuralBuildTimeField.setAccessible(true);
        }
        return lastStructuralBuildTimeField.getLong(state);
    }

    private static StringSet getStructurallyChangedTypes(State state)
            throws Exception {
        if (structurallyChangedTypesField == null) {
            structurallyChangedTypesField = State.class.getDeclaredField("structurallyChangedTypes");
            structurallyChangedTypesField.setAccessible(true);
        }
        return (StringSet)structurallyChangedTypesField.get(state);
    }
	
	// Cached for performance reasons
	private static java.lang.reflect.Field lastStructuralBuildTimeField = null;
	private static java.lang.reflect.Field structurallyChangedTypesField = null;
	
}
