Revision: 19658
          http://sourceforge.net/p/gate/code/19658
Author:   markagreenwood
Date:     2016-10-10 06:46:13 +0000 (Mon, 10 Oct 2016)
Log Message:
-----------
a bunch more bu/performance fixes including some copied over from trunk

Modified Paths:
--------------
    gate/branches/sawdust2/gate-core/findbugs-excluded.xml
    
gate/branches/sawdust2/gate-core/src/main/java/gate/annotation/AnnotationSetImpl.java
    
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ConllDocumentFormat.java
    
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentImpl.java
    
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentStaxUtils.java
    gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/MimeType.java
    
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ObjectWrapper.java

Removed Paths:
-------------
    
gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/SyncEclipse.java

Modified: gate/branches/sawdust2/gate-core/findbugs-excluded.xml
===================================================================
--- gate/branches/sawdust2/gate-core/findbugs-excluded.xml      2016-10-10 
01:22:45 UTC (rev 19657)
+++ gate/branches/sawdust2/gate-core/findbugs-excluded.xml      2016-10-10 
06:46:13 UTC (rev 19658)
@@ -6,6 +6,7 @@
          ignore these. We'll revist this issue at some future point.
          -->
          <Bug pattern="DM_DEFAULT_ENCODING" />
+         <Bug pattern="DM_CONVERT_CASE" />
       </Or>
    </Match>
 

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/annotation/AnnotationSetImpl.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/annotation/AnnotationSetImpl.java
       2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/annotation/AnnotationSetImpl.java
       2016-10-10 06:46:13 UTC (rev 19658)
@@ -278,12 +278,12 @@
 
   /** Remove from the offset indices. */
   protected void removeFromOffsetIndex(Annotation a) {
-    if(nodesByOffset != null) {
+    /*if(nodesByOffset != null) {
       // knowing when a node is no longer needed would require keeping a
       // reference
       // count on annotations, or using a weak reference to the nodes in
       // nodesByOffset
-    }
+    }*/
     if(annotsByStartNode != null) {
       Integer id = a.getStartNode().getId();
       // might be an annotation or an annotationset
@@ -686,7 +686,7 @@
   public AnnotationSet get(String type, FeatureMap constraints, Long offset) {
     // select by offset
     AnnotationSet nextAnnots = get(offset);
-    if(nextAnnots == null) return emptyAS();
+    
     // select by type and constraints from the next annots
     return nextAnnots.get(type, constraints);
   } // get(type, constraints, offset)

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ConllDocumentFormat.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ConllDocumentFormat.java
        2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ConllDocumentFormat.java
        2016-10-10 06:46:13 UTC (rev 19658)
@@ -203,8 +203,7 @@
    * end offset on an annotation that has one, but chop it off if it's still 
unspecified.
    */
   private void finishAllTags(Map<String, Annotandum> annsUnderway, 
List<Annotandum> annsFinished, long cutoff) {
-    for (String key : annsUnderway.keySet()) {
-      Annotandum ann = annsUnderway.get(key);
+    for (Annotandum ann : annsUnderway.values()) {
       if (ann.endOffset == null) {
         ann.endOffset = cutoff;
       }

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentImpl.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentImpl.java   
    2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentImpl.java   
    2016-10-10 06:46:13 UTC (rev 19658)
@@ -2243,37 +2243,33 @@
    * Constant used in the inner class AnnotationComparator to order annotations
    * on their start offset
    */
-  private final int ORDER_ON_START_OFFSET = 0;
+  private static final int ORDER_ON_START_OFFSET = 0;
 
   /**
    * Constant used in the inner class AnnotationComparator to order annotations
    * on their end offset
    */
-  private final int ORDER_ON_END_OFFSET = 1;
+  private static final int ORDER_ON_END_OFFSET = 1;
 
   /**
    * Constant used in the inner class AnnotationComparator to order annotations
    * on their ID
    */
-  private final int ORDER_ON_ANNOT_ID = 2;
+  private static final int ORDER_ON_ANNOT_ID = 2;
 
   /**
    * Constant used in the inner class AnnotationComparator to order annotations
    * ascending
    */
-  private final int ASC = 3;
+  private static final int ASC = 3;
 
   /**
    * Constant used in the inner class AnnotationComparator to order annotations
    * descending
    */
-  private final int DESC = -3;
+  private static final int DESC = -3;
 
   /**
-   * The range that the content comes from at the source URL (or null if none).
-   */
-  // protected Long[] sourceUrlOffsets;
-  /**
    * The start of the range that the content comes from at the source URL (or
    * null if none).
    */
@@ -2320,7 +2316,7 @@
   } // set StringContent
 
   /** Is the document markup-aware? */
-  protected Boolean markupAware = new Boolean(false);
+  protected Boolean markupAware = Boolean.FALSE;
 
   // /** Hash code */
   // public int hashCode() {
@@ -2370,7 +2366,7 @@
   static final long serialVersionUID = -8456893608311510260L;
 
   /** Inner class needed to compare annotations */
-  class AnnotationComparator implements Comparator<Annotation> {
+  static class AnnotationComparator implements Comparator<Annotation> {
     int orderOn = -1;
 
     int orderType = ASC;

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentStaxUtils.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentStaxUtils.java
  2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/DocumentStaxUtils.java
  2016-10-10 06:46:13 UTC (rev 19658)
@@ -287,7 +287,7 @@
         int startNodeId = Integer.parseInt(xsr.getAttributeValue(null,
                 "StartNode"));
         if(nodeIdToOffsetMap != null) {
-          Long startOffset = nodeIdToOffsetMap.get(new Integer(startNodeId));
+          Long startOffset = nodeIdToOffsetMap.get(startNodeId);
           if(startOffset != null) {
             annObj.setStart(startOffset);
           }
@@ -298,7 +298,7 @@
         }
         else {
           // no offset map, so just use the ID as an offset
-          annObj.setStart(new Long(startNodeId));
+          annObj.setStart(Long.valueOf(startNodeId));
         }
       }
       catch(NumberFormatException nfe) {
@@ -310,7 +310,7 @@
         int endNodeId = Integer
                 .parseInt(xsr.getAttributeValue(null, "EndNode"));
         if(nodeIdToOffsetMap != null) {
-          Long endOffset = nodeIdToOffsetMap.get(new Integer(endNodeId));
+          Long endOffset = nodeIdToOffsetMap.get(endNodeId);
           if(endOffset != null) {
             annObj.setEnd(endOffset);
           }
@@ -321,7 +321,7 @@
         }
         else {
           // no offset map, so just use the ID as an offset
-          annObj.setEnd(new Long(endNodeId));
+          annObj.setEnd(Long.valueOf(endNodeId));
         }
       }
       catch(NumberFormatException nfe) {
@@ -437,10 +437,6 @@
       while((eventType = xsr.next()) != XMLStreamConstants.END_ELEMENT) {
         switch(eventType) {
           case XMLStreamConstants.CHARACTERS:
-            stringRep.append(xsr.getTextCharacters(), xsr.getTextStart(),
-                    xsr.getTextLength());
-            break;
-
           case XMLStreamConstants.CDATA:
             stringRep.append(xsr.getTextCharacters(), xsr.getTextStart(),
                     xsr.getTextLength());
@@ -503,7 +499,7 @@
           }
           try {
             Integer id = Integer.valueOf(idString);
-            Long offset = new Long(textBuf.length());
+            Long offset = Long.valueOf(textBuf.length());
             nodeIdToOffsetMap.put(id, offset);
           }
           catch(NumberFormatException nfe) {
@@ -584,15 +580,11 @@
     while((eventType = xsr.next()) != XMLStreamConstants.END_ELEMENT) {
       switch(eventType) {
         case XMLStreamConstants.CHARACTERS:
+        case XMLStreamConstants.CDATA:
           stringRep.append(xsr.getTextCharacters(), xsr.getTextStart(), xsr
                   .getTextLength());
           break;
                  
-        case XMLStreamConstants.CDATA:
-          stringRep.append(xsr.getTextCharacters(), xsr.getTextStart(), xsr
-                  .getTextLength());
-          break;
-
         case XMLStreamConstants.START_ELEMENT:
           throw new XMLStreamException("Elements not allowed within "
                   + "feature name or value element.", xsr.getLocation());
@@ -809,17 +801,15 @@
       AnnotationObject annObj = new AnnotationObject();
       annObj.setElemName(xsr.getAttributeValue(null, "type"));
       try {
-        int from = Integer.parseInt(xsr.getAttributeValue(null, "from"));
-        annObj.setStart(new Long(from));
+        annObj.setStart(Long.valueOf(xsr.getAttributeValue(null, "from")));
       }
       catch(NumberFormatException nfe) {
         throw new XMLStreamException(
                 "Non-integer value found for struct/@from", xsr.getLocation());
       }
 
-      try {
-        int to = Integer.parseInt(xsr.getAttributeValue(null, "to"));
-        annObj.setEnd(new Long(to));
+      try{
+        annObj.setEnd(Long.valueOf(xsr.getAttributeValue(null, "to")));
       }
       catch(NumberFormatException nfe) {
         throw new XMLStreamException("Non-integer value found for struct/@to",
@@ -1057,13 +1047,14 @@
     // Serialize all others AnnotationSets
     // namedAnnotSets is a Map containing all other named Annotation
     // Sets.
-    Iterator<String> iter = annotationSets.keySet().iterator();
-    while(iter.hasNext()) {
-      String annotationSetName = iter.next();
+    //Iterator<String> iter = annotationSets.keySet().iterator();
+    //while(iter.hasNext()) {
+    for (Map.Entry<String,Collection<Annotation>> entry : 
annotationSets.entrySet()) {
+      String annotationSetName = entry.getKey();//iter.next();
       // ignore the null entry, if present - we've already handled that
       // above
       if(annotationSetName != null) {
-        Collection<Annotation> annots = annotationSets.get(annotationSetName);
+        Collection<Annotation> annots = 
entry.getValue();//annotationSets.get(annotationSetName);
         xsw.writeComment(" Named annotation set ");
         newLine(xsw);
         newLine(xsw);
@@ -1076,7 +1067,7 @@
       }// End if
     }// End while
     
-    iter = annotationSets.keySet().iterator();
+    Iterator<String> iter = annotationSets.keySet().iterator();
     while(iter.hasNext()) {
       
       writeRelationSet(doc.getAnnotations(iter.next()).getRelations(), xsw,
@@ -1477,32 +1468,31 @@
 
     Set<Object> keySet = features.keySet();
     Iterator<Object> keySetIterator = keySet.iterator();
-    FEATURES:while(keySetIterator.hasNext()) {
+    //FEATURES:
+    while(keySetIterator.hasNext()) {
       Object key = keySetIterator.next();
       Object value = features.get(key);
       if(key != null && value != null) {
         String keyClassName = null;
-        String keyItemClassName = null;
+        //String keyItemClassName = null;
         String valueClassName = null;
-        String valueItemClassName = null;
+        //String valueItemClassName = null;
         String key2String = key.toString();
         String value2String = value.toString();
-        Object item = null;
-        // Test key if it is String, Number or Collection
+        //Object item = null;
+        // Test key if it is String, Number
         if(key instanceof java.lang.String || 
-           key instanceof java.lang.Number || 
-           key instanceof java.util.Collection) {
+           key instanceof java.lang.Number) {
           keyClassName = key.getClass().getName();
         } else {
           keyClassName = ObjectWrapper.class.getName();
           key2String = new ObjectWrapper(key).toString();
         }
           
-        // Test value if it is String, Number or Collection
+        // Test value if it is String, Number
         if(value instanceof java.lang.String
                 || value instanceof java.lang.Number
-                || value instanceof java.lang.Boolean
-                || value instanceof java.util.Collection){
+                || value instanceof java.lang.Boolean){
           valueClassName = value.getClass().getName();
         } else {
           valueClassName = ObjectWrapper.class.getName();
@@ -1512,51 +1502,8 @@
         // Features and values that are not Strings, Numbers, Booleans or
         // collections
         // will be discarded.
-        if(keyClassName == null || valueClassName == null) continue;
+        //if(keyClassName == null || valueClassName == null) continue;
 
-        // If key is collection serialize the collection in a specific
-        // format
-        if(key instanceof java.util.Collection) {
-          StringBuffer keyStrBuff = new StringBuffer();
-          Iterator<?> iter = ((Collection<?>)key).iterator();
-          if(iter.hasNext()) {
-            item = iter.next();
-            if(item == null) continue FEATURES;
-            if(item instanceof java.lang.Number)
-              keyItemClassName = item.getClass().getName();
-            else keyItemClassName = String.class.getName();
-            keyStrBuff.append(item.toString());
-          }// End if
-          while(iter.hasNext()) {
-            item = iter.next();
-            if(item == null) continue FEATURES;
-            keyStrBuff.append(";").append(item.toString());
-          }// End while
-          key2String = keyStrBuff.toString();
-        }// End if
-
-        // If key is collection serialize the colection in a specific
-        // format
-        if(value instanceof java.util.Collection) {
-          StringBuffer valueStrBuff = new StringBuffer();
-          Iterator<?> iter = ((Collection<?>)value).iterator();
-          if(iter.hasNext()) {
-            item = iter.next();
-            if(item == null) continue FEATURES;
-            if(item instanceof java.lang.Number 
-                || item instanceof java.lang.Boolean)
-              valueItemClassName = item.getClass().getName();
-            else valueItemClassName = String.class.getName();
-            valueStrBuff.append(item.toString());
-          }// End if
-          while(iter.hasNext()) {
-            item = iter.next();
-            if(item == null) continue FEATURES;
-            valueStrBuff.append(";").append(item.toString());
-          }// End while
-          value2String = valueStrBuff.toString();
-        }// End if
-
         xsw.writeStartElement(namespaceURI, "Feature");
         xsw.writeCharacters("\n  ");
 
@@ -1565,9 +1512,9 @@
         if(keyClassName != null) {
           xsw.writeAttribute("className", keyClassName);
         }
-        if(keyItemClassName != null) {
-          xsw.writeAttribute("itemClassName", keyItemClassName);
-        }
+        //if(keyItemClassName != null) {
+        //  xsw.writeAttribute("itemClassName", keyItemClassName);
+        //}
         xsw.writeCharacters(key2String);
         xsw.writeEndElement();
         xsw.writeCharacters("\n  ");
@@ -1577,9 +1524,9 @@
         if(valueClassName != null) {
           xsw.writeAttribute("className", valueClassName);
         }
-        if(valueItemClassName != null) {
-          xsw.writeAttribute("itemClassName", valueItemClassName);
-        }
+        //if(valueItemClassName != null) {
+        //  xsw.writeAttribute("itemClassName", valueItemClassName);
+        //}
         writeCharactersOrCDATA(xsw,
                 replaceXMLIllegalCharactersInString(value2String));
         xsw.writeEndElement();

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/MimeType.java
===================================================================
--- gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/MimeType.java   
2016-10-10 01:22:45 UTC (rev 19657)
+++ gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/MimeType.java   
2016-10-10 06:46:13 UTC (rev 19658)
@@ -1,5 +1,5 @@
 /*
- *  TextualDocumentFormat.java
+ *  MimeType.java
  *
  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
@@ -40,20 +40,32 @@
    * @return true if the two MIME Types are the same.
    */
   @Override
-  public boolean equals(Object other){
-    return other != null && type.equals(((MimeType)other).getType()) &&
-           subtype.equals(((MimeType)other).getSubtype());
+  public boolean equals(Object obj) {
+    if(this == obj) return true;
+    if(obj == null) return false;
+    if(getClass() != obj.getClass()) return false;
+    MimeType other = (MimeType)obj;
+    if(subtype == null) {
+      if(other.subtype != null) return false;
+    } else if(!subtype.equals(other.subtype)) return false;
+    if(type == null) {
+      if(other.type != null) return false;
+    } else if(!type.equals(other.type)) return false;
+    return true;
   }
-
+  
   /**
    * The hashcode is composed (by addition) from the hashcodes for the type and
    * subtype.
    * @return and integer.
    */
   @Override
-  public int hashCode(){
-    return (type == null ? 0 : type.hashCode()) +
-            (subtype == null ? 0 : subtype.hashCode());
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((subtype == null) ? 0 : subtype.hashCode());
+    result = prime * result + ((type == null) ? 0 : type.hashCode());
+    return result;
   }
 
   /**

Modified: 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ObjectWrapper.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ObjectWrapper.java  
    2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/corpora/ObjectWrapper.java  
    2016-10-10 06:46:13 UTC (rev 19658)
@@ -59,7 +59,6 @@
     Object other = xstream.fromXML(xmlSerialisation);
     if(other instanceof ObjectWrapper) {
       this.value = ((ObjectWrapper)other).value;
-      other = null;
     } else {
       log.error("Value de-serialised from XML is of type \"" + 
           other.getClass().getName() + "\", instead of expected \"" + 

Deleted: 
gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/SyncEclipse.java
===================================================================
--- 
gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/SyncEclipse.java   
    2016-10-10 01:22:45 UTC (rev 19657)
+++ 
gate/branches/sawdust2/gate-core/src/main/java/gate/util/ant/SyncEclipse.java   
    2016-10-10 06:46:13 UTC (rev 19658)
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 1995-2012, The University of Sheffield. See the file
- * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
- * 
- * This file is part of GATE (see http://gate.ac.uk/), and is free software,
- * licenced under the GNU Library General Public License, Version 2, June 1991
- * (in the distribution as file licence.html, and also available at
- * http://gate.ac.uk/gate/licence.html).
- * 
- * Mark A. Greenwood, 21/01/2012
- * 
- * $Id$
- */
-
-package gate.util.ant;
-
-import gate.util.ExtensionFileFilter;
-import gate.util.Files;
-import gate.util.persistence.PersistenceManager;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileWriter;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-import org.jdom.output.Format;
-import org.jdom.output.XMLOutputter;
-import org.jdom.xpath.XPath;
-
-/**
- * An ANT task that syncs an Eclipse classpath file against a folder of jar
- * files. Once the task has completed all jar files in the specified folder 
will
- * be mentioned within the Eclipse classpath file and any jars that were
- * mentioned in the classpath file as being with the specified folder and which
- * no longer exist will have been removed.
- */
-public class SyncEclipse extends Task {
-
-  private XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()
-      .setIndent("\t"));
-
-  private File dir, classpath;
-
-  private boolean recursive = true;
-  
-  private boolean verbose = false;
-
-  public boolean isRecursive() {
-    return recursive;
-  }
-
-  public void setRecursive(boolean recursive) {
-    this.recursive = recursive;
-  }
-  
-  public boolean isVerbose() {
-    return verbose;
-  }
-
-  public void setVerbose(boolean verbose) {
-    this.verbose = verbose;
-  }
-
-  public File getDir() {
-    return dir;
-  }
-
-  public void setDir(File dir) {
-    this.dir = dir;
-  }
-
-  public File getClasspathFile() {
-    return classpath;
-  }
-
-  public void setClasspathFile(File classpath) {
-    this.classpath = classpath;
-  }
-
-  @Override
-  public void execute() throws BuildException {
-    if(dir == null)
-      throw new BuildException("Please specify a directory", getLocation());
-
-    if(!dir.exists() || !dir.isDirectory())
-      throw new BuildException("Specified directory doesn't exist",
-          getLocation());
-
-    FileFilter ff = new ExtensionFileFilter("JAR Files", "jar");
-
-    if(classpath == null)
-      classpath = new File(getProject().getBaseDir(), ".classpath");
-
-    if(!classpath.exists() || !classpath.isFile())
-      throw new BuildException("Eclipse classpath file can't be located",
-          getLocation());
-
-    Set<File> jars = new HashSet<File>();
-    for(File f : Arrays.asList(recursive
-        ? Files.listFilesRecursively(dir, ff)
-        : dir.listFiles(ff))) {
-      if(!f.isDirectory()) jars.add(f);
-    }
-
-    boolean dirty = false;
-
-    try {
-      SAXBuilder builder = new SAXBuilder();
-      Document classpathDoc = builder.build(classpath);
-
-      @SuppressWarnings("unchecked")
-      List<Element> libEntries =
-          XPath.newInstance("/classpath/classpathentry[@kind='lib']")
-              .selectNodes(classpathDoc);
-
-      String relative = 
PersistenceManager.getRelativePath(classpath.toURI().toURL(), 
dir.toURI().toURL());
-            
-      for(Element e : libEntries) {
-        String path = e.getAttributeValue("path");
-        if(path.startsWith(relative)) {
-          File f = new File(classpath.getParentFile(), path);
-          if(jars.contains(f)) {
-            if (verbose) System.out.println("KEEPING: " + path);
-            jars.remove(f);
-          } else {
-            dirty = true;
-            if (verbose) System.out.println("REMOVED: " + path);
-            Element parent = e.getParentElement();
-            parent.removeContent(e);
-          }
-        }
-      }
-
-      if(!jars.isEmpty()) {
-        dirty = true;
-        for(File f : jars) {
-          String path =
-              PersistenceManager.getRelativePath(classpath.toURI().toURL(), f
-                  .toURI().toURL());
-          if (verbose) System.out.println("ADDED: " + path);
-          Element libElement =
-              new Element("classpathentry").setAttribute("kind", "lib")
-                  .setAttribute("exported", "true").setAttribute("path", path);
-          classpathDoc.getRootElement().addContent(libElement);
-        }
-      }
-
-      if(dirty) {
-        outputter.output(classpathDoc, new FileWriter(classpath));
-      }
-
-    } catch(Exception e) {
-      throw new BuildException(e, getLocation());
-    }
-  }
-}

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
GATE-cvs mailing list
GATE-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gate-cvs

Reply via email to