Ignore:
Timestamp:
2014-08-06T19:33:57+02:00 (11 years ago)
Author:
donvip
Message:

[josm_opendata] add more unit tests, fix Java 7 warnings

Location:
applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/NeptuneReader.java

    r30532 r30568  
    3939import neptune.TridentObjectType;
    4040
     41import org.openstreetmap.josm.Main;
    4142import org.openstreetmap.josm.data.coor.LatLon;
    4243import org.openstreetmap.josm.data.osm.DataSet;
     
    103104                                Validator validator = schema.newValidator();
    104105                                validator.validate(xmlFile);
    105                                 System.out.println(xmlFile.getSystemId() + " is valid");
     106                                Main.info(xmlFile.getSystemId() + " is valid");
    106107                                return true;
    107108                        } catch (SAXException e) {
    108                                 System.out.println(xmlFile.getSystemId() + " is NOT valid");
    109                                 System.out.println("Reason: " + e.getLocalizedMessage());
     109                                Main.error(xmlFile.getSystemId() + " is NOT valid");
     110                                Main.error("Reason: " + e.getLocalizedMessage());
    110111                        } catch (IOException e) {
    111                                 System.out.println(xmlFile.getSystemId() + " is NOT valid");
    112                                 System.out.println("Reason: " + e.getLocalizedMessage());
     112                            Main.error(xmlFile.getSystemId() + " is NOT valid");
     113                            Main.error("Reason: " + e.getLocalizedMessage());
    113114                        } finally {
    114115                                try {
     
    119120                        }
    120121                } catch (FileNotFoundException e) {
    121                         System.err.println(e.getMessage());
     122                    Main.error(e.getMessage());
    122123                }
    123124               
     
    317318                                                } else {
    318319                                                        // TODO
    319                                                         System.out.println("TODO: handle StopPoint "+childId);
     320                                                        Main.info("TODO: handle StopPoint "+childId);
    320321                                                }
    321322
    322323                                        } else {
    323                                                 System.err.println("Unsupported child: "+childId);
     324                                                Main.warn("Unsupported child: "+childId);
    324325                                        }
    325326                                }
    326327                        } else if (sa.getStopAreaExtension().getAreaType().equals(ChouetteAreaType.BOARDING_POSITION)) {
    327                                 //System.out.println("skipping StopArea with type "+sa.getStopAreaExtension().getAreaType()+": "+sa.getObjectId());
     328                                //Main.info("skipping StopArea with type "+sa.getStopAreaExtension().getAreaType()+": "+sa.getObjectId());
    328329                        } else {
    329                                 System.err.println("Unsupported StopArea type: "+sa.getStopAreaExtension().getAreaType());
     330                            Main.warn("Unsupported StopArea type: "+sa.getStopAreaExtension().getAreaType());
    330331                        }
    331332                }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/OsmDownloader.java

    r30563 r30568  
    1515                        try {
    1616                                String oapiServer = Main.pref.get(OdConstants.PREF_OAPI, OdConstants.DEFAULT_OAPI);
    17                                 System.out.println(oapiReq);
     17                                Main.info(oapiReq);
    1818                                String oapiReqEnc = URLEncoder.encode(oapiReq, OdConstants.UTF8);
    1919                                Main.main.menu.openLocation.openUrl(false, oapiServer+"data="+oapiReqEnc);
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ArchiveReader.java

    r30563 r30568  
    77import java.io.IOException;
    88import java.util.ArrayList;
     9import java.util.Collection;
     10import java.util.Collections;
     11import java.util.HashMap;
    912import java.util.List;
     13import java.util.Map;
    1014
    1115import javax.xml.bind.JAXBException;
     
    5660   
    5761    protected abstract String getTaskMessage();
    58        
    59     public DataSet parseDoc(final ProgressMonitor progressMonitor) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
    60        
    61         final File temp = OdUtils.createTempDir();
     62   
     63    protected Collection<File> getDocsToParse(final File temp, final ProgressMonitor progressMonitor) throws FileNotFoundException, IOException {
    6264        final List<File> candidates = new ArrayList<>();
    6365       
     66        if (progressMonitor != null) {
     67            progressMonitor.beginTask(getTaskMessage());
     68        }
     69        extractArchive(temp, candidates);
     70       
     71        if (promptUser && candidates.size() > 1) {
     72            DialogPrompter<CandidateChooser> prompt = new DialogPrompter<CandidateChooser>() {
     73                @Override
     74                protected CandidateChooser buildDialog() {
     75                    return new CandidateChooser(progressMonitor.getWindowParent(), candidates);
     76                }
     77            };
     78            if (prompt.promptInEdt().getValue() == 1) {
     79                return Collections.singleton(prompt.getDialog().getSelectedFile());
     80            }
     81        } else if (!candidates.isEmpty()) {
     82            return candidates;
     83        }
     84        return Collections.emptyList();
     85    }
     86   
     87    public Map<File, DataSet> parseDocs(final ProgressMonitor progressMonitor) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException {
     88        Map<File, DataSet> result = new HashMap<>();
     89        File temp = OdUtils.createTempDir();
    6490        try {
     91            file = null;
     92            for (File f : getDocsToParse(temp, progressMonitor)) {
     93                DataSet from = getDataForFile(f, progressMonitor);
     94                if (from != null) {
     95                    result.put(f, from);
     96                }
     97            }
     98        } finally {
     99            OdUtils.deleteDir(temp);
    65100            if (progressMonitor != null) {
    66                 progressMonitor.beginTask(getTaskMessage());
     101                progressMonitor.finishTask();
    67102            }
    68             extractArchive(temp, candidates);
    69            
    70             file = null;
    71            
    72             if (promptUser && candidates.size() > 1) {
    73                 DialogPrompter<CandidateChooser> prompt = new DialogPrompter<CandidateChooser>() {
    74                     @Override
    75                     protected CandidateChooser buildDialog() {
    76                         return new CandidateChooser(progressMonitor.getWindowParent(), candidates);
    77                     }
    78                 };
    79                 if (prompt.promptInEdt().getValue() == 1) {
    80                     file = prompt.getDialog().getSelectedFile();
    81                 }
    82             } else if (!candidates.isEmpty()) {
    83                 file = candidates.get(0);
     103        }
     104        return result;
     105    }
     106   
     107    public DataSet parseDoc(final ProgressMonitor progressMonitor) throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException  {
     108        File temp = OdUtils.createTempDir();
     109       
     110        try {
     111            file = null;       
     112            Collection<File> files = getDocsToParse(temp, progressMonitor);
     113            if (!files.isEmpty()) {
     114                file = files.iterator().next();
    84115            }
    85116           
    86             DataSet from = getDataForFile(progressMonitor);
     117            DataSet from = getDataForFile(file, progressMonitor);
    87118            if (from != null) {
    88119                ds = from;
     
    100131    }
    101132
    102     protected DataSet getDataForFile(final ProgressMonitor progressMonitor)
     133    protected DataSet getDataForFile(File f, final ProgressMonitor progressMonitor)
    103134            throws FileNotFoundException, IOException, XMLStreamException, FactoryConfigurationError, JAXBException {
    104         if (file == null) {
     135        if (f == null) {
    105136            return null;
    106         } else if (!file.exists()) {
    107             Main.warn("File does not exist: "+file.getPath());
     137        } else if (!f.exists()) {
     138            Main.warn("File does not exist: "+f.getPath());
    108139            return null;
    109140        } else {
     141            Main.info("Parsing file "+f.getName());
    110142            DataSet from = null;
    111             FileInputStream in = new FileInputStream(file);
     143            FileInputStream in = new FileInputStream(f);
    112144            ProgressMonitor instance = null;
    113145            if (progressMonitor != null) {
    114146                instance = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
    115147            }
    116             if (file.getName().toLowerCase().endsWith(OdConstants.CSV_EXT)) {
     148            if (f.getName().toLowerCase().endsWith(OdConstants.CSV_EXT)) {
    117149                from = CsvReader.parseDataSet(in, handler, instance);
    118             } else if (file.getName().toLowerCase().endsWith(OdConstants.KML_EXT)) {
     150            } else if (f.getName().toLowerCase().endsWith(OdConstants.KML_EXT)) {
    119151                from = KmlReader.parseDataSet(in, instance);
    120             } else if (file.getName().toLowerCase().endsWith(OdConstants.KMZ_EXT)) {
     152            } else if (f.getName().toLowerCase().endsWith(OdConstants.KMZ_EXT)) {
    121153                from = KmzReader.parseDataSet(in, instance);
    122             } else if (file.getName().toLowerCase().endsWith(OdConstants.XLS_EXT)) {
     154            } else if (f.getName().toLowerCase().endsWith(OdConstants.XLS_EXT)) {
    123155                from = XlsReader.parseDataSet(in, handler, instance);
    124             } else if (file.getName().toLowerCase().endsWith(OdConstants.ODS_EXT)) {
     156            } else if (f.getName().toLowerCase().endsWith(OdConstants.ODS_EXT)) {
    125157                from = OdsReader.parseDataSet(in, handler, instance);
    126             } else if (file.getName().toLowerCase().endsWith(OdConstants.SHP_EXT)) {
    127                 from = ShpReader.parseDataSet(in, file, handler, instance);
    128             } else if (file.getName().toLowerCase().endsWith(OdConstants.MIF_EXT)) {
    129                 from = MifReader.parseDataSet(in, file, handler, instance);
    130             } else if (file.getName().toLowerCase().endsWith(OdConstants.TAB_EXT)) {
    131                 from = TabReader.parseDataSet(in, file, handler, instance);
    132             } else if (file.getName().toLowerCase().endsWith(OdConstants.GML_EXT)) {
     158            } else if (f.getName().toLowerCase().endsWith(OdConstants.SHP_EXT)) {
     159                from = ShpReader.parseDataSet(in, f, handler, instance);
     160            } else if (f.getName().toLowerCase().endsWith(OdConstants.MIF_EXT)) {
     161                from = MifReader.parseDataSet(in, f, handler, instance);
     162            } else if (f.getName().toLowerCase().endsWith(OdConstants.TAB_EXT)) {
     163                from = TabReader.parseDataSet(in, f, handler, instance);
     164            } else if (f.getName().toLowerCase().endsWith(OdConstants.GML_EXT)) {
    133165                from = GmlReader.parseDataSet(in, handler, instance);
    134             } else if (file.getName().toLowerCase().endsWith(OdConstants.XML_EXT)) {
    135                 if (OdPlugin.getInstance().xmlImporter.acceptFile(file)) {
     166            } else if (f.getName().toLowerCase().endsWith(OdConstants.XML_EXT)) {
     167                if (OdPlugin.getInstance().xmlImporter.acceptFile(f)) {
    136168                    from = NeptuneReader.parseDataSet(in, handler, instance);
    137169                } else {
    138                     System.err.println("Unsupported XML file: "+file.getName());
     170                    System.err.println("Unsupported XML file: "+f.getName());
    139171                }
    140172               
    141173            } else {
    142                 System.err.println("Unsupported file extension: "+file.getName());
     174                System.err.println("Unsupported file extension: "+f.getName());
    143175            }
    144176            return from;
     
    151183            if (entryName.toLowerCase().endsWith("."+ext)) {
    152184                candidates.add(file);
    153                 System.out.println(entryName);
    154185                break;
    155186            }
     
    159190                || OdPlugin.getInstance().xmlImporter.acceptFile(file))) {
    160191            candidates.add(file);
    161             System.out.println(entryName);
    162192        }
    163193    }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/SevenZipReader.java

    r30436 r30568  
    1111import java.io.OutputStream;
    1212import java.util.List;
     13import java.util.Map;
    1314
    1415import javax.xml.bind.JAXBException;
     
    5758    }
    5859
    59     @Override protected String getTaskMessage() {
     60    public static Map<File, DataSet> parseDataSets(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance, boolean promptUser)
     61            throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException {
     62        return new SevenZipReader(in, handler, promptUser).parseDocs(instance);
     63    }
     64
     65    @Override
     66    protected String getTaskMessage() {
    6067        return tr("Reading 7Zip file...");
    6168    }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java

    r30340 r30568  
    1010import java.io.InputStream;
    1111import java.util.List;
     12import java.util.Map;
    1213import java.util.zip.ZipEntry;
    1314import java.util.zip.ZipInputStream;
     
    3637                return new ZipReader(in, handler, promptUser).parseDoc(instance);
    3738        }
     39
     40    public static Map<File, DataSet> parseDataSets(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance, boolean promptUser)
     41            throws IOException, XMLStreamException, FactoryConfigurationError, JAXBException {
     42        return new ZipReader(in, handler, promptUser).parseDocs(instance);
     43    }
    3844
    3945    protected void extractArchive(final File temp, final List<File> candidates) throws IOException, FileNotFoundException {
     
    7581    }
    7682
    77     @Override protected String getTaskMessage() {
     83    @Override
     84    protected String getTaskMessage() {
    7885        return tr("Reading Zip file...");
    7986    }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/DefaultShpHandler.java

    r30563 r30568  
    5151                boolean res = Math.abs(a - b) <= Main.pref.getDouble(OdConstants.PREF_CRS_COMPARISON_TOLERANCE, OdConstants.DEFAULT_CRS_COMPARISON_TOLERANCE);
    5252                if (Main.pref.getBoolean(OdConstants.PREF_CRS_COMPARISON_DEBUG, false)) {
    53                         System.out.println("Comparing "+a+" and "+b+" -> "+res);
     53                        Main.debug("Comparing "+a+" and "+b+" -> "+res);
    5454                }
    5555                return res;
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/GeographicReader.java

    r30563 r30568  
    55
    66import java.awt.Component;
     7import java.awt.GraphicsEnvironment;
    78import java.awt.Image;
    89import java.util.ArrayList;
     10import java.util.Arrays;
    911import java.util.HashMap;
    1012import java.util.List;
     
    200202   
    201203        private static final void compareDebug(CoordinateReferenceSystem crs1, CoordinateReferenceSystem crs2) {
    202                 System.out.println("-- COMPARING "+crs1.getName()+" WITH "+crs2.getName()+" --");
     204                Main.debug("-- COMPARING "+crs1.getName()+" WITH "+crs2.getName()+" --");
    203205                compareDebug("class", crs1.getClass(), crs2.getClass());
    204206                CoordinateSystem cs1 = crs1.getCoordinateSystem();
     
    229231                        }
    230232                }
    231                 System.out.println("-- COMPARING FINISHED --");
     233                Main.debug("-- COMPARING FINISHED --");
    232234        }
    233235       
     
    245247
    246248        private static final boolean compareDebug(String text, boolean result, Object o1, Object o2) {
    247                 System.out.println(text + ": " + result + "("+o1+", "+o2+")");
     249            Main.debug(text + ": " + result + "("+o1+", "+o2+")");
    248250                return result;
    249251        }
     
    253255                        transform = CRS.findMathTransform(crs, wgs84);
    254256                } catch (OperationNotFoundException e) {
    255                         System.out.println(crs.getName()+": "+e.getMessage()); // Bursa wolf parameters required.
     257                        Main.info(crs.getName()+": "+e.getMessage()); // Bursa wolf parameters required.
    256258                       
    257259                        if (findSimiliarCrs) {
     
    267269                                                                Main.pref.getDouble(OdConstants.PREF_CRS_COMPARISON_TOLERANCE, OdConstants.DEFAULT_CRS_COMPARISON_TOLERANCE));
    268270                                                if (((AbstractCRS)candidate).equals((AbstractIdentifiedObject)crs, false)) {
    269                                                         System.out.println("Found a potential CRS: "+candidate.getName());
     271                                                        Main.info("Found a potential CRS: "+candidate.getName());
    270272                                                        candidates.add(candidate);
    271273                                                } else if (Main.pref.getBoolean(OdConstants.PREF_CRS_COMPARISON_DEBUG, false)) {
     
    281283                               
    282284                                if (candidates.size() > 1) {
    283                                         System.err.println("Found several potential CRS.");//TODO: ask user which one to use
     285                                        Main.warn("Found several potential CRS: "+Arrays.toString(candidates.toArray()));
     286                                        // TODO: ask user which one to use
    284287                                }
    285288                               
     
    300303                                                transform = handler.findMathTransform(crs, wgs84, false);
    301304                                        } catch (OperationNotFoundException ex) {
    302                                                 System.out.println(crs.getName()+": "+ex.getMessage()); // Bursa wolf parameters required.
     305                                            Main.warn(crs.getName()+": "+ex.getMessage()); // Bursa wolf parameters required.
    303306                                        }
    304307                                } else {
     
    310313                                                        }
    311314                                                } catch (OperationNotFoundException ex) {
    312                                                         System.out.println(crs.getName()+": "+ex.getMessage()); // Bursa wolf parameters required.
     315                                                    Main.warn(crs.getName()+": "+ex.getMessage()); // Bursa wolf parameters required.
    313316                                                }
    314317                                        }
    315318                                }
    316319                                if (transform == null) {
    317                                         // ask user before trying lenient method
    318                                         if (warnLenientMethod(parent, crs)) {
     320                                        // ask user before trying lenient method, unless in headless mode (unit tests)
     321                                        if (!GraphicsEnvironment.isHeadless() && warnLenientMethod(parent, crs)) {
    319322                                                // User canceled
    320323                                                throw new UserCancelException();
    321324                                        }
    322                                         System.out.println("Searching for a lenient math transform.");
     325                                        Main.info("Searching for a lenient math transform.");
    323326                                        transform = CRS.findMathTransform(crs, wgs84, true);
    324327                                }
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/GmlReader.java

    r30563 r30568  
    107107       
    108108        private void findCRS(String srs) throws NoSuchAuthorityCodeException, FactoryException {
    109                 System.out.println("Finding CRS for "+srs);
     109                Main.info("Finding CRS for "+srs);
    110110                if (gmlHandler != null) {
    111111                        crs = gmlHandler.getCrsFor(srs);
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java

    r30567 r30568  
    158158                        } else {
    159159                                // Debug unknown geometry
    160                                 System.out.println("\ttype: "+geometry.getType());
    161                                 System.out.println("\tbounds: "+geometry.getBounds());
    162                                 System.out.println("\tdescriptor: "+desc);
    163                                 System.out.println("\tname: "+geometry.getName());
    164                                 System.out.println("\tvalue: "+geometry.getValue());
    165                                 System.out.println("\tid: "+geometry.getIdentifier());
    166                                 System.out.println("-------------------------------------------------------------");
     160                                Main.debug("\ttype: "+geometry.getType());
     161                                Main.debug("\tbounds: "+geometry.getBounds());
     162                                Main.debug("\tdescriptor: "+desc);
     163                                Main.debug("\tname: "+geometry.getName());
     164                                Main.debug("\tvalue: "+geometry.getValue());
     165                                Main.debug("\tid: "+geometry.getIdentifier());
     166                                Main.debug("-------------------------------------------------------------");
    167167                        }
    168168                       
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvReader.java

    r30563 r30568  
    88import java.nio.charset.Charset;
    99
     10import org.openstreetmap.josm.Main;
    1011import org.openstreetmap.josm.data.osm.DataSet;
    1112import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    4344                        if (csvHandler == null || csvHandler.getSeparator() == null || ";".equals(csvHandler.getSeparator())) {
    4445                                // If default sep has been used, try comma
    45                                 System.out.println(e.getMessage());
     46                                Main.warn(e.getMessage());
    4647                                csvReader.sep = ",";
    4748                                return csvReader.doParse(csvReader.splitLine(), instance);
     
    5455        @Override
    5556        protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
    56                 System.out.println("Parsing CSV file using charset "+charset+" and separator '"+sep+"'");
     57                Main.info("Parsing CSV file using charset "+charset+" and separator '"+sep+"'");
    5758
    5859                reader = new BufferedReader(new InputStreamReader(in, charset));
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsDocument.java

    r30563 r30568  
    1111import org.jopendocument.io.SaxContentUnmarshaller;
    1212import org.jopendocument.model.OpenDocument;
     13import org.openstreetmap.josm.Main;
    1314import org.xml.sax.InputSource;
    1415import org.xml.sax.XMLReader;
     
    4445                if (entry.getName().equals("content.xml")) {
    4546                    rdr.setContentHandler(contentHandler);
    46                     System.out.println("Parsing content.xml");
     47                    Main.info("Parsing content.xml");
    4748                    rdr.parse(getEntryInputSource(zis));
    4849                        contentParsed = true;
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsReader.java

    r30532 r30568  
    1313import org.jopendocument.model.table.TableTableRow;
    1414import org.jopendocument.model.text.TextP;
     15import org.openstreetmap.josm.Main;
    1516import org.openstreetmap.josm.data.osm.DataSet;
    1617import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    3839        protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
    3940                try {
    40                         System.out.println("Parsing ODS file");
     41                        Main.info("Parsing ODS file");
    4142                        doc = new OdsDocument(in);
    4243                        List<OfficeSpreadsheet> spreadsheets = doc.getBody().getOfficeSpreadsheets();
     
    6263
    6364                        if (rowIndex % 5000 == 0) {
    64                                 System.out.println("Lines read: "+rowIndex);
     65                                Main.info("Lines read: "+rowIndex);
    6566                        }
    6667
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/SpreadSheetReader.java

    r30563 r30568  
    100100       
    101101        public DataSet doParse(String[] header, ProgressMonitor progressMonitor) throws IOException {
    102                 System.out.println("Header: "+Arrays.toString(header));
     102                Main.info("Header: "+Arrays.toString(header));
    103103               
    104104                Map<ProjectionPatterns, List<CoordinateColumns>> projColumns = new HashMap<>();
     
    175175                }
    176176               
    177                 System.out.println("Loading data using projections "+message);
     177                Main.info("Loading data using projections "+message);
    178178               
    179179                final DataSet ds = new DataSet();
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsReader.java

    r30532 r30568  
    1414import org.apache.poi.ss.usermodel.Sheet;
    1515import org.apache.poi.ss.usermodel.Workbook;
     16import org.openstreetmap.josm.Main;
    1617import org.openstreetmap.josm.data.osm.DataSet;
    1718import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    3536        @Override
    3637        protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
    37                 System.out.println("Parsing XLS file");
     38            Main.info("Parsing XLS file");
    3839                try {
    3940                        wb = new HSSFWorkbook(new POIFSFileSystem(in));
Note: See TracChangeset for help on using the changeset viewer.