Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/TestDGN.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/TestDGN.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/TestDGN.java	(revision 509)
@@ -0,0 +1,100 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.io.File;
+import java.net.URL;
+import org.gvsig.fmap.dal.DALLocator;
+import org.gvsig.fmap.dal.DataManager;
+
+import org.gvsig.fmap.dal.DataStoreParameters;
+import org.gvsig.fmap.dal.exception.DataException;
+import org.gvsig.fmap.dal.feature.FeatureStore;
+import org.gvsig.tools.junit.AbstractLibraryAutoInitTestCase;
+
+import static junit.framework.Assert.assertNotNull;
+
+public class TestDGN extends AbstractLibraryAutoInitTestCase {
+
+	private File file_prueba = null;
+        private DataManager dataManager = null;
+
+        @Override
+        protected void doSetUp() throws Exception {
+            URL res = TestDGN.class.getResource("data/prueba.dgn");
+            this.file_prueba = new File(res.getFile());
+            this.dataManager = DALLocator.getDataManager();
+        }
+
+        
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see
+	 * org.gvsig.fmap.dal.feature.BaseTestFeatureStore#getDefaultDataStoreParameters
+	 * ()
+	 */
+	public DataStoreParameters getDefaultDataStoreParameters()
+			throws DataException {
+            
+		DGNOpenStoreParameters dgnParameters = null;
+
+		dgnParameters = (DGNOpenStoreParameters) dataManager
+				.createStoreParameters(DGNStoreProvider.NAME);
+
+		dgnParameters.setFile(file_prueba.getAbsolutePath());
+		dgnParameters.setCRS("EPSG:23030");
+		return dgnParameters;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see org.gvsig.fmap.dal.feature.BaseTestFeatureStore#hasExplorer()
+	 */
+	public boolean hasExplorer() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean usesResources() {
+		return true;
+	}
+
+
+	public void testLegendAndLabeling() throws Exception {
+		FeatureStore store = (FeatureStore) dataManager.openStore(
+                        DGNStoreProvider.NAME,
+                        getDefaultDataStoreParameters()
+                );
+
+		assertNotNull(store.invokeDynMethod("getLegend", null));
+		assertNotNull(store.invokeDynMethod("getLabeling", null));
+		store.dispose();
+	}
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/data/prueba.dgn
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/data/prueba.dgn
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNMetadata.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNMetadata.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNMetadata.xml	(revision 509)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+Definitions of metadata fields of a shp file.  
+ -->
+<definitions>
+  <version>1.0.0</version>
+  <classes>
+    
+    <class name="DGN" namespace="Metadata">
+      <extends>
+      	<class namespace="Metadata" name="SpatialProvider"/>
+      </extends>
+      <description>Metadata of a DGN store</description>
+      <fields>
+      </fields>
+    </class>
+
+  </classes>
+</definitions>  
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNParameters.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNParameters.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/org/gvsig/fmap/dal/store/dgn/DGNParameters.xml	(revision 509)
@@ -0,0 +1,157 @@
+<?xml version= "1.0 "?>
+<definitions>
+  <version>1.0.0</version>
+  <classes>
+    <class name="DGN">
+      <extends>
+      	<class namespace="dal" name="ProviderParameters"/>
+      </extends>
+      <description>Store the parameters need to open a dgn file</description>
+      <fields>
+        
+        <!-- General -->
+        <field name="file" type="file" mandatory="true">
+          <description>dgn file</description>
+        </field>
+        <field name="CRS" type="crs" mandatory="true">
+          <description>The coordinate reference system used in this dgn file</description>
+        </field>
+        <field name="LoadMode" label="Load mode" defaultValue="0" type="integer" mandatory="false">
+          <description>Set the strategy to use for loading DGN elements</description>
+     	  <availableValues>
+            <value label="Plain">0</value>
+            <value label="Group elements (1)">1</value>
+     	  </availableValues>
+        </field>
+        <field name="sortByGeometryType" label="Sort by geometry type" type="Boolean" defaultValue="true" mandatory="false">
+          <description>If checked sort the rows of table by the geometry type (none,suface,curve,point)</description>
+        </field>
+        <field name="force2d" label="Force 2D" type="Boolean" defaultValue="false" mandatory="false">
+          <description>If checked and DGN has Z dimension create all geometry in 2D and ignore the Zs.</description>
+        </field>
+        <field name="Reload" label="Reload" type="Boolean" defaultValue="false" mandatory="false">
+          <description>Reload an already loaded DGN as a new layer</description>
+        </field>
+        <field name="groupby" label="Field for group" type="String" defaultValue="" mandatory="false">
+          <description>The field name to use for grouping rows</description>
+        </field>
+        <field name="GroupGeometriesOperation" label="Group geometries as" type="integer" defaultValue="0" mandatory="false">
+          <description>If a 'group by' is applied, apply this operation to the resultant geometries</description>
+     	  <availableValues>
+            <value label="None, return the agregate">0</value>
+            <value label="Convexhull">1</value>
+            <value label="Union">2</value>
+            <value label="Intersection">3</value>
+            <value label="Convert to points">4</value>
+            <value label="Convert to line">5</value>
+            <value label="Convert to poligon">7</value>
+            <value label="Convert to poligon and fix it">7</value>
+     	  </availableValues>
+        </field>
+
+        <!-- Advanced -->
+        <field name="ignoreZ" label="Ignore Z" type="Boolean" defaultValue="false" mandatory="false">
+          <description>If checked and DGN has Z dimension, set all Zs to 0.</description>
+        </field>
+        <field name="useZAsElevation" label="Use Z as elevation" type="Boolean" defaultValue="false" mandatory="false" group="Advanced">
+          <description>If set, use the Z value to fill the field elevation.</description>
+        </field>
+        <field name="elevationFactor" label="Elevation factor" type="Double" defaultValue="1" mandatory="false" group="Advanced">
+          <description>Factor to apply to elevation when is retrived from the Z coordinate.</description>
+        </field>
+        <field name="roundElevation" label="Round elevation" type="Boolean" defaultValue="false" mandatory="false" group="Advanced">
+          <description>If set, round the elevation to a integer value. This only apply when get elevation from the coordinete Z.</description>
+        </field>
+        <field name="LinkFilterIndex" label="Link filter index" type="integer" defaultValue="0" mandatory="false" group="Advanced">
+          <description>If set, return the link with this index</description>
+        </field>
+        <field name="LinkFilterType" label="Link filter type" type="integer" defaultValue="" mandatory="false" group="Advanced">
+          <description>If set, return the link with this type</description>
+        </field>
+        <field name="LinkFilterEntity" label="Link filter entity" type="integer" defaultValue="" mandatory="false" group="Advanced">
+          <description>If set, return the link with this entity</description>
+        </field>
+        <field name="LinkFilterMS" label="Link filter MSLink" type="integer" defaultValue="" mandatory="false" group="Advanced">
+          <description>If set, return the link with this MSLink</description>
+        </field>
+        <field name="LinkFilterData" label="Link filter Data" type="string" defaultValue="" mandatory="false" group="Advanced">
+          <description>This is a regular expresion. If set, return the link that match this regular expresion in the data of link represented in hexadecimal value</description>
+        </field>
+
+        <!-- Filter -->
+        <field name="levelFilter" label="Level" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this level. Can use regular expresion to specify the filter.</description>
+        </field>
+        <field name="colorFilter" label="Color" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this color. Can use regular expresion to specify the filter.</description>
+        </field>
+        <field name="styleFilter" label="Style" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this style. Can use regular expresion to specify the filter.</description>
+        </field>
+        <field name="weightFilter" label="Weight" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this weight. Can use regular expresion to specify the filter.</description>
+        </field>
+        <field name="typeFilter" label="Type" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this type</description>
+        </field>
+        <field name="stypeFilter" label="SType" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this stype</description>
+        </field>
+        <field name="groupFilter" label="Group" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this group</description>
+        </field>
+        <field name="idFilter" label="Id" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements with this id</description>
+        </field>
+        <field name="textFilter" label="Text" group="Filter" type="String" defaultValue="" mandatory="false">
+          <description>If specified load only elements that match this text</description>
+        </field>
+        <field name="geomtypeFilter" label="Geometry type" group="Filter" defaultValue="0" type="Integer" mandatory="false">
+          <description>If specified load only elements with this type of geometry</description>
+     	  <availableValues>
+            <value label="All">0</value>
+            <value label="Points">1</value>
+            <value label="Lines">2</value>
+            <value label="Poligons">3</value>
+     	  </availableValues>
+        </field>
+        <field name="skipCorruptGeometries" label="Skip corrupt geometries" group="Filter" type="Boolean" defaultValue="false" mandatory="false">
+          <description>If specified skip corrupt geometries</description>
+        </field>
+        <field name="cropOperationFilter" label="Crop operation" group="Filter" defaultValue="1" type="Integer" mandatory="false">
+          <description>If specified load only elements with this type of geometry</description>
+     	  <availableValues>
+            <value label="None">0</value>
+            <value label="Contains">1</value>
+            <value label="Covered by">2</value>
+            <value label="Covers">3</value>
+            <value label="Crosses">4</value>
+            <value label="Disjoint">5</value>
+            <value label="Intersect">6</value>
+            <value label="Overlaps">7</value>
+            <value label="Touches">8</value>
+            <value label="With in">9</value>
+     	  </availableValues>
+        </field>
+        <field name="cropFilter" label="Crop to" group="Filter" type="Geometry" defaultValue="" mandatory="false">
+          <description>Crop the result to this value</description>
+        </field>
+        
+                        
+        <!-- Debug -->
+        <field name="XMLFile" label="Output XML file" type="file" group="Debug" mandatory="false">
+          <description>Generate XML file with DGN dump in this file</description>
+        </field>
+        <!--
+        <field name="debugOptions" label="Debug options" type="String" group="Debug" mandatory="false">
+          <description></description>
+        </field>
+        -->
+        <field name="logErrors" label="log errors" group="Debug" type="Boolean" defaultValue="false" mandatory="false">
+          <description>If checked the log of errors are enabled</description>
+        </field>
+
+      </fields>
+    </class>
+  </classes>
+</definitions>  
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/META-INF/services/org.gvsig.tools.library.Library	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/resources/META-INF/services/org.gvsig.tools.library.Library	(revision 509)
@@ -0,0 +1,2 @@
+org.gvsig.fmap.dal.store.dgn.DGNLibrary
+org.gvsig.fmap.dal.store.dgn.legend.DGNLegendLibrary
\ No newline at end of file
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNFilesystemServerProvider.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNFilesystemServerProvider.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNFilesystemServerProvider.java	(revision 509)
@@ -0,0 +1,91 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.io.File;
+
+import org.gvsig.fmap.dal.DataServerExplorer;
+import org.gvsig.fmap.dal.DataStoreParameters;
+import org.gvsig.fmap.dal.NewDataStoreParameters;
+import org.gvsig.fmap.dal.exception.CreateException;
+import org.gvsig.fmap.dal.exception.DataException;
+import org.gvsig.fmap.dal.exception.FileNotFoundException;
+import org.gvsig.fmap.dal.exception.RemoveException;
+import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
+import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.impl.AbstractFilesystemServerExplorerProvider;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerProvider;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerProviderServices;
+
+public class DGNFilesystemServerProvider extends AbstractFilesystemServerExplorerProvider
+        implements FilesystemServerExplorerProvider, ResourceConsumer {
+
+    @Override
+    public String getDataStoreProviderName() {
+        return DGNStoreProvider.NAME;
+    }
+
+    @Override
+    public int getMode() {
+        return DataServerExplorer.MODE_FEATURE | DataServerExplorer.MODE_GEOMETRY;
+    }
+
+    @Override
+    public boolean accept(File pathname) {
+        return (pathname.getName().toLowerCase().endsWith(".dgn"));
+    }
+
+    @Override
+    public String getDescription() {
+        return DGNStoreProvider.DESCRIPTION;
+    }
+
+    @Override
+    public boolean canCreate() {
+        return false;
+    }
+
+    @Override
+    public boolean canCreate(NewDataStoreParameters parameters) {
+        return false;
+    }
+
+    @Override
+    public void create(NewDataStoreParameters parameters, boolean overwrite)
+            throws CreateException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NewDataStoreParameters getCreateParameters() throws DataException {
+        return null;
+    }
+
+    @Override
+    public void initialize(
+            FilesystemServerExplorerProviderServices serverExplorer) {
+    }
+
+    @Override
+    public void remove(DataStoreParameters parameters) throws RemoveException {
+        File file = new File(((DGNOpenStoreParameters) parameters).getFileName());
+        if (!file.exists()) {
+            throw new RemoveException(this.getDataStoreProviderName(),
+                    new FileNotFoundException(file));
+        }
+        if (!file.delete()) {
+            // FIXME throws ???
+        }
+
+    }
+
+    @Override
+    public boolean closeResourceRequested(ResourceProvider resource) {
+        // while it is using a resource anyone can't close it
+        return false;
+    }
+
+    @Override
+    public void resourceChanged(ResourceProvider resource) {
+        //Do nothing
+    }
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProvider.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProvider.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProvider.java	(revision 509)
@@ -0,0 +1,1593 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.PathIterator;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.cresques.cts.IProjection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.gvsig.fmap.dal.DALLocator;
+import org.gvsig.fmap.dal.DataManager;
+import org.gvsig.fmap.dal.DataServerExplorer;
+import org.gvsig.fmap.dal.DataStoreNotification;
+import org.gvsig.fmap.dal.DataTypes;
+import org.gvsig.fmap.dal.FileHelper;
+import org.gvsig.fmap.dal.exception.DataException;
+import org.gvsig.fmap.dal.exception.InitializeException;
+import org.gvsig.fmap.dal.exception.LoadException;
+import org.gvsig.fmap.dal.exception.OpenException;
+import org.gvsig.fmap.dal.exception.ReadException;
+import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
+import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
+import org.gvsig.fmap.dal.feature.EditableFeatureType;
+import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
+import org.gvsig.fmap.dal.feature.FeatureType;
+import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
+import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
+import org.gvsig.fmap.dal.resource.ResourceAction;
+import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
+import org.gvsig.fmap.dal.resource.file.FileResource;
+import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
+import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
+import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNElemArc;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNElemComplexHeader;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCore;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNElemMultiPoint;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNElemText;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNFileHeader;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNLink;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNPoint;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.fmap.geom.Geometry.SUBTYPES;
+import org.gvsig.fmap.geom.Geometry.TYPES;
+import org.gvsig.fmap.geom.GeometryLocator;
+import org.gvsig.fmap.geom.GeometryManager;
+import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
+import org.gvsig.fmap.geom.exception.CreateGeometryException;
+import org.gvsig.fmap.geom.primitive.Envelope;
+import org.gvsig.fmap.geom.primitive.GeneralPathX;
+import org.gvsig.fmap.geom.primitive.IGeneralPathX;
+import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
+import org.gvsig.fmap.geom.primitive.Point;
+import org.gvsig.fmap.geom.type.GeometryType;
+import org.gvsig.tools.dynobject.exception.DynMethodException;
+
+public class DGNStoreProvider extends AbstractMemoryStoreProvider implements
+    ResourceConsumer {
+
+    private static final Logger logger = LoggerFactory.getLogger(DGNStoreProvider.class);
+
+    public static final String NAME = "DGN";
+    public static final String DESCRIPTION = "DGN file";
+
+    public static final String METADATA_DEFINITION_NAME = NAME;
+    public static final String METADATA_DEFINITION_DESCRIPTION = "DGN File Store";
+
+    public static final int LOAD_MODE_PLAIN = 0;
+    public static final int LOAD_MODE_GROUP1 = 1;
+
+    public static final int CROP_OPERATION_NONE = 0;
+    public static final int CROP_OPERATION_CONTAINS = 1;
+    public static final int CROP_OPERATION_COVERS = 2;
+    public static final int CROP_OPERATION_COVEREDBY = 3;
+    public static final int CROP_OPERATION_CROSSES = 4;
+    public static final int CROP_OPERATION_DISJOINT = 5;
+    public static final int CROP_OPERATION_INTERSECT = 6;
+    public static final int CROP_OPERATION_OVERLAPS = 7;
+    public static final int CROP_OPERATION_TOUCHES = 8;
+    public static final int CROP_OPERATION_WITHIN = 9;
+
+    public static final int GROUP_GEOMETRIES_NONE = 0;
+    public static final int GROUP_GEOMETRIES_CONVEXHULL = 1;
+    public static final int GROUP_GEOMETRIES_UNION = 2;
+    public static final int GROUP_GEOMETRIES_INTERSECTION = 3;
+    public static final int GROUP_GEOMETRIES_TOPOINTS = 4;
+    public static final int GROUP_GEOMETRIES_TOLINES = 5;
+    public static final int GROUP_GEOMETRIES_TOPOLYGONS = 6;
+    public static final int GROUP_GEOMETRIES_TOPOLYGONS_FIX = 7;
+
+    public static final String NAME_FIELD_ID = "ID";
+    public static final String NAME_FIELD_GEOMETRY = "Geometry";
+    public static final String NAME_FIELD_TYPE = "Type";
+    public static final String NAME_FIELD_STYPE = "SType";
+    public static final String NAME_FIELD_ENTITY = "Entity";
+    public static final String NAME_FIELD_LEVEL = "Layer";
+    public static final String NAME_FIELD_COLOR = "Color";
+    public static final String NAME_FIELD_FILLCOLOR = "FillColor";
+    public static final String NAME_FIELD_ELEVATION = "Elevation";
+    public static final String NAME_FIELD_WEIGHT = "Weight";
+    public static final String NAME_FIELD_TEXT = "Text";
+    public static final String NAME_FIELD_HEIGHTTEXT = "HeightText";
+    public static final String NAME_FIELD_HEIGHTTEXTRAW = "HeightTextRaw";
+    public static final String NAME_FIELD_ROTATIONTEXT = "Rotation";
+    public static final String NAME_FIELD_STYLE = "Style";
+    public static final String NAME_FIELD_GROUP = "Group";
+    public static final String NAME_FIELD_ISSHAPE = "IsShape";
+    public static final String NAME_FIELD_ISCOMPLEXSHAPEHEADER = "IsComplexShapeHeader";
+    public static final String NAME_FIELD_ISHOLE = "IsHole";
+    public static final String NAME_FIELD_ISCOMPLEX = "IsComplex";
+    public static final String NAME_FIELD_PARENTID = "ParentId";
+    public static final String NAME_FIELD_SCALE = "Scale";
+    public static final String NAME_FIELD_LINKS_COUNT = "LinksCount";
+    public static final String NAME_FIELD_LINK_INDEX = "LinkIndex";
+    public static final String NAME_FIELD_LINK_TYPE = "LinkType";
+    public static final String NAME_FIELD_LINK_ENTITY = "LinkEntity";
+    public static final String NAME_FIELD_LINK_MS = "LinkMS";
+    public static final String NAME_FIELD_LINK_LENGTH = "LinkLength";
+    public static final String NAME_FIELD_LINK_DATA = "LinkData";
+    public static final String NAME_FIELD_DATA = "Data";
+
+    private int ID_FIELD_ID;
+    private int ID_FIELD_TYPE;
+    private int ID_FIELD_STYPE;
+    private int ID_FIELD_ENTITY;
+    private int ID_FIELD_LEVEL;
+    private int ID_FIELD_COLOR;
+    private int ID_FIELD_FILLCOLOR;
+    private int ID_FIELD_ELEVATION;
+    private int ID_FIELD_WEIGHT;
+    private int ID_FIELD_TEXT;
+    private int ID_FIELD_HEIGHTTEXT;
+    private int ID_FIELD_HEIGHTTEXTRAW;
+    private int ID_FIELD_ROTATIONTEXT;
+    private int ID_FIELD_STYLE;
+    private int ID_FIELD_GROUP;
+    private int ID_FIELD_LAYER;
+    private int ID_FIELD_ISCOMPLEXSHAPEHEADER;
+    private int ID_FIELD_ISSHAPE;
+    private int ID_FIELD_ISHOLE;
+    private int ID_FIELD_ISCOMPLEX;
+    private int ID_FIELD_PARENT;
+    private int ID_FIELD_SCALE;
+    private int ID_FIELD_LINKS_COUNT;
+    private int ID_FIELD_LINK_INDEX;
+    private int ID_FIELD_LINK_TYPE;
+    private int ID_FIELD_LINK_ENTITY;
+    private int ID_FIELD_LINK_MS;
+    private int ID_FIELD_LINK_LENGTH;
+    private int ID_FIELD_LINK_DATA;
+    private int ID_FIELD_DATA;
+    private int ID_FIELD_GEOMETRY;
+    private int MAX_FIELD_ID;
+
+    private IProjection projection;
+    private ResourceProvider resource;
+    private LegendBuilder legendBuilder;
+
+    private long counterNewsOIDs = 0;
+    protected GeometryManager geomManager = GeometryLocator
+        .getGeometryManager();
+
+    private int groupByFieldIndex = -2;
+    private Map<Object, FeatureProvider> groupedFeatures = null;
+
+    DGNData dgndata = null;
+
+    public DGNStoreProvider(DGNOpenStoreParameters parameters,
+        DataStoreProviderServices storeServices) throws InitializeException {
+        super(parameters, storeServices, FileHelper
+            .newMetadataContainer(METADATA_DEFINITION_NAME));
+
+        counterNewsOIDs = 0;
+        // projection = CRSFactory.getCRS(getParameters().getSRSID());
+
+        File file = getDGNParameters().getFile();
+        resource =
+            this.createResource(FileResource.NAME,
+                new Object[] { file.getAbsolutePath() });
+
+        resource.addConsumer(this);
+
+        this.projection = this.getDGNParameters().getCRS();
+
+        try {
+            legendBuilder =
+                (LegendBuilder) this.invokeDynMethod(
+                    LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
+        } catch (DynMethodException e) {
+            legendBuilder = null;
+        } catch (Exception e) {
+            throw new InitializeException(e);
+        }
+
+        this.initializeFeatureTypes();
+
+    }
+
+    private DGNOpenStoreParameters getDGNParameters() {
+        return (DGNOpenStoreParameters) this.getParameters();
+    }
+
+    public String getProviderName() {
+        return NAME;
+    }
+
+    public boolean allowWrite() {
+        // not yet
+        return false;
+    }
+
+    public Object getLegend() throws OpenException {
+        this.open();
+        if (legendBuilder == null) {
+            return null;
+        }
+        return legendBuilder.getLegend();
+    }
+
+    public Object getLabeling() throws OpenException {
+        this.open();
+        if (legendBuilder == null) {
+            return null;
+        }
+        return legendBuilder.getLabeling();
+    }
+
+    private class DGNData {
+
+        public List<FeatureProvider> data = null;
+        public FeatureType defaultFType = null;
+        public List<FeatureType> fTypes = null;
+        public Envelope envelope = null;
+        public IProjection projection;
+        public LegendBuilder legendBuilder;
+
+        public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
+            if (envelope == null) {
+                return null;
+            }
+            try {
+                return (Envelope) envelope.clone();
+            } catch (CloneNotSupportedException ex) {
+                logger.warn("Can't clone envelope.", ex);
+                return null;
+            }
+        }
+    }
+
+    public static class TimeCounter {
+
+        private static final Logger logger = LoggerFactory
+            .getLogger(TimeCounter.class);
+
+        private long counter = 0;
+        private Date t1;
+        private Date t2;
+
+        public void start() {
+            this.t1 = new Date();
+            this.t2 = this.t1;
+        }
+
+        public void restart() {
+            this.t1 = new Date();
+            this.t2 = this.t1;
+            this.counter = 0;
+        }
+
+        public void stop() {
+            this.t2 = new Date();
+            this.counter += this.t2.getTime() - this.t1.getTime();
+        }
+
+        public long get() {
+            return this.counter;
+        }
+
+        public void log(String msg) {
+            logger.debug("Time " + get() + " ms. " + msg);
+        }
+
+        public void restart(String msg) {
+            this.stop();
+            this.log(msg);
+            this.restart();
+        }
+    }
+
+    public void open() throws OpenException {
+        if (this.data != null) {
+            return;
+        }
+        try {
+            getResource().execute(new ResourceAction() {
+
+                public Object run() throws Exception {
+
+                    TimeCounter tc = new TimeCounter();
+                    tc.start();
+
+                    FeatureStoreProviderServices storeProviderServices = getStoreServices();
+                    if (dgndata == null && !(getDGNParameters().useReload())) {
+                        if (resource.getData() != null) {
+                            dgndata =
+                                (DGNData) ((Map) resource.getData())
+                                    .get(projection.getAbrev()); // OJO no es del todo correcto (puede llevar reproyeccion)
+                        } else {
+                            resource.setData(new HashMap());
+                        }
+                    }
+                    tc.restart("Retrive data from resource (data=" + dgndata + ")");
+
+                    if (dgndata == null) {
+                        dgndata = new DGNData();
+                        dgndata.data = new ArrayList();
+                        data = dgndata.data;
+                        counterNewsOIDs = 0;
+                        Reader reader = new Reader().initialice(getMemoryProvider(), (File) resource.get(), projection, legendBuilder);
+                        reader.begin(storeProviderServices);
+                        dgndata.defaultFType = reader.getDefaultType().getNotEditableCopy();
+                        List types = new ArrayList();
+                        Iterator it = reader.getTypes().iterator();
+                        EditableFeatureType fType;
+                        while (it.hasNext()) {
+                            fType = (EditableFeatureType) it.next();
+                            if (fType.getId().equals(dgndata.defaultFType.getId())) {
+                                types.add(dgndata.defaultFType);
+                            } else {
+                                types.add(fType.getNotEditableCopy());
+                            }
+                        }
+                        dgndata.fTypes = types;
+
+                        resource.notifyOpen();
+                        storeProviderServices.setFeatureTypes(dgndata.fTypes, dgndata.defaultFType);
+                        reader.load();
+                        dgndata.envelope = reader.getEnvelope();
+                        dgndata.legendBuilder = legendBuilder;
+                        dgndata.projection = projection;
+                        reader.end();
+                        if (resource.getData() == null) {
+                            resource.setData(new HashMap());
+                        }
+                        ((Map) resource.getData()).put(projection.getAbrev(),dgndata); // OJO la reproyeccion
+                        tc.restart("Loaded data from file (data=" + dgndata + ")");
+                        resource.notifyClose();
+                    }
+                    // El feature type no lo compartimos entre las instancias del
+                    // mismo resource ya que puede cambiar en funcion del filtro.
+                    // Por lo menos el geometry-type.
+                    List<FeatureType> featureTypes = getFeatureTypes(storeProviderServices);
+
+                    tc.restart("Created featuretype (featureTypes=" + featureTypes + ")");
+
+                    PostProcessFeatures postProcess = new PostProcessFeatures(getDGNParameters(), featureTypes.get(0));
+                    if (postProcess.hasOperations()) {
+                        data = postProcess.apply(dgndata.data);
+                        setDynValue("Envelope", postProcess.getEnvelope());
+                    } else {
+                        data = dgndata.data;
+                        setDynValue("Envelope", dgndata.getEnvelopeCopy());
+                    }
+                    tc.restart("PostProcessFeatures");
+
+                    legendBuilder = dgndata.legendBuilder;
+                    storeProviderServices.setFeatureTypes(featureTypes, featureTypes.get(0));
+                    setDynValue("CRS", projection);
+                    counterNewsOIDs = data.size();
+                    tc.restart("load finished.");
+                    return null;
+                }
+            });
+        } catch (Exception e) {
+            data = null;
+            try {
+                throw new OpenException(resource.getName(), e);
+            } catch (AccessResourceException e1) {
+                throw new OpenException(getProviderName(), e);
+            }
+        }
+    }
+
+    public DataServerExplorer getExplorer() throws ReadException {
+        DataManager manager = DALLocator.getDataManager();
+        FilesystemServerExplorerParameters params;
+        try {
+            params = (FilesystemServerExplorerParameters) manager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
+            params.setRoot(this.getDGNParameters().getFile().getParent());
+            return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
+        } catch (DataException e) {
+            throw new ReadException(this.getProviderName(), e);
+        } catch (ValidateDataParametersException e) {
+            throw new ReadException(this.getProviderName(), e);
+        }
+
+    }
+
+    public void performChanges(Iterator deleteds, Iterator inserteds,
+        Iterator updateds, Iterator originalFeatureTypesUpdated)
+        throws PerformEditingException {
+        // FIXME Exception
+        throw new UnsupportedOperationException();
+    }
+
+    public List getFeatureTypes(FeatureStoreProviderServices store) {
+        //FIXME: Habr�a que distinguir cuando se va a crear un DGN 3D o 2D, de momento siempre 3D
+        return getFeatureTypes(store, Geometry.SUBTYPES.GEOM3D);
+    }
+
+    private List getFeatureTypes(FeatureStoreProviderServices store, int subtype) {
+        EditableFeatureType featureType = store.createFeatureType(getName());
+
+        featureType.setHasOID(true);
+
+        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_PARENT = featureType.add(NAME_FIELD_PARENTID, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        // FIXME: Cual es el size y el valor por defecto para Entity ?
+        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY, DataTypes.STRING, 100)
+                .setDefaultValue("").getIndex();
+
+        // FIXME: Cual es el size de Layer ?
+        ID_FIELD_LEVEL = featureType.add(NAME_FIELD_LEVEL, DataTypes.STRING, 100)
+                .setDefaultValue("default").getIndex();
+        ID_FIELD_LAYER = ID_FIELD_LEVEL;
+
+        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        // FIXME: Cual es el size de Text ?
+        ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT, DataTypes.STRING, 100)
+                .setDefaultValue("").getIndex();
+
+        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT, DataTypes.DOUBLE)
+                .setDefaultValue(Double.valueOf(10)).getIndex();
+
+        ID_FIELD_HEIGHTTEXTRAW = featureType.add(NAME_FIELD_HEIGHTTEXTRAW, DataTypes.DOUBLE)
+                .setDefaultValue(Double.valueOf(10)).getIndex();
+
+        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT, DataTypes.DOUBLE)
+                .setDefaultValue(Double.valueOf(0)).getIndex();
+
+        ID_FIELD_TYPE = featureType.add(NAME_FIELD_TYPE, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_STYPE = featureType.add(NAME_FIELD_STYPE, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_FILLCOLOR = featureType.add(NAME_FIELD_FILLCOLOR, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_STYLE = featureType.add(NAME_FIELD_STYLE, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION, DataTypes.DOUBLE)
+                .setDefaultValue(Double.valueOf(0)).getIndex();
+
+        ID_FIELD_WEIGHT = featureType.add(NAME_FIELD_WEIGHT, DataTypes.DOUBLE)
+                .setDefaultValue(Double.valueOf(0)).getIndex();
+
+        ID_FIELD_GROUP = featureType.add(NAME_FIELD_GROUP, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_ISSHAPE = featureType.add(NAME_FIELD_ISSHAPE, DataTypes.BOOLEAN)
+                .setDefaultValue(Boolean.FALSE).getIndex();
+
+        ID_FIELD_ISCOMPLEXSHAPEHEADER = featureType.add(NAME_FIELD_ISCOMPLEXSHAPEHEADER, DataTypes.BOOLEAN)
+                .setDefaultValue(Boolean.FALSE).getIndex();
+
+        ID_FIELD_ISHOLE = featureType.add(NAME_FIELD_ISHOLE, DataTypes.BOOLEAN)
+                .setDefaultValue(Boolean.FALSE).getIndex();
+
+        ID_FIELD_ISCOMPLEX = featureType.add(NAME_FIELD_ISCOMPLEX, DataTypes.BOOLEAN)
+                .setDefaultValue(Boolean.FALSE).getIndex();
+
+        ID_FIELD_SCALE = featureType.add(NAME_FIELD_SCALE, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINKS_COUNT = featureType.add(NAME_FIELD_LINKS_COUNT, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_INDEX = featureType.add(NAME_FIELD_LINK_INDEX, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_ENTITY = featureType.add(NAME_FIELD_LINK_ENTITY, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_TYPE = featureType.add(NAME_FIELD_LINK_TYPE, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_MS = featureType.add(NAME_FIELD_LINK_MS, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_LENGTH = featureType.add(NAME_FIELD_LINK_LENGTH, DataTypes.INT)
+                .setDefaultValue(Integer.valueOf(0)).getIndex();
+
+        ID_FIELD_LINK_DATA = featureType.add(NAME_FIELD_LINK_DATA, DataTypes.STRING, 512)
+                .setDefaultValue("").getIndex();
+
+        ID_FIELD_DATA = featureType.add(NAME_FIELD_DATA, DataTypes.STRING, 512)
+                .setDefaultValue("").getIndex();
+
+        EditableFeatureAttributeDescriptor attr = featureType.add(NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
+        attr.setSRS(this.projection);
+        int geometryTypeToUse = getDGNParameters().getGeometryTypeFilter();
+        if (getDGNParameters().getGroupBy() != null) {
+            switch (getDGNParameters().getGroupGeometriesOperation()) {
+            case GROUP_GEOMETRIES_NONE:
+            case GROUP_GEOMETRIES_UNION:
+            case GROUP_GEOMETRIES_INTERSECTION:
+                break;
+            case GROUP_GEOMETRIES_TOPOINTS:
+                geometryTypeToUse = Geometry.TYPES.MULTIPOINT;
+                break;
+            case GROUP_GEOMETRIES_TOLINES:
+                geometryTypeToUse = Geometry.TYPES.MULTICURVE;
+                break;
+            case GROUP_GEOMETRIES_TOPOLYGONS:
+            case GROUP_GEOMETRIES_TOPOLYGONS_FIX:
+            case GROUP_GEOMETRIES_CONVEXHULL:
+                geometryTypeToUse = Geometry.TYPES.MULTISURFACE;
+                break;
+            }
+        }
+        try {
+            attr.setGeometryType(GeometryLocator.getGeometryManager()
+                .getGeometryType(geometryTypeToUse, subtype));
+        } catch (Exception e) {
+            attr.setGeometryType(geometryTypeToUse);
+            attr.setGeometrySubType(subtype);
+        }
+        ID_FIELD_GEOMETRY = attr.getIndex();
+
+        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
+
+        MAX_FIELD_ID = featureType.size() - 1;
+
+        List types = new ArrayList();
+        types.add(featureType);
+
+        return types;
+    }
+
+    public class Reader {
+
+        private File file;
+        private IProjection projection;
+        private List types;
+        private LegendBuilder leyendBuilder;
+        private AbstractMemoryStoreProvider storeProvider;
+        private Envelope envelope;
+
+        public Reader initialice(AbstractMemoryStoreProvider storeProvider, File file,
+            IProjection projection, LegendBuilder leyendBuilder) {
+            this.storeProvider = storeProvider;
+            this.file = file;
+            this.projection = projection;
+            this.leyendBuilder = leyendBuilder;
+            if (leyendBuilder != null) {
+                leyendBuilder.initialize(storeProvider);
+            }
+            return this;
+        }
+
+        public Envelope getEnvelope() {
+            return this.envelope;
+        }
+
+        public void begin(FeatureStoreProviderServices storeProviderServices) {
+
+            types = getFeatureTypes(storeProviderServices);
+
+            if (leyendBuilder != null) {
+                leyendBuilder.begin();
+            }
+
+        }
+
+        public void end() {
+            if (leyendBuilder != null) {
+                leyendBuilder.end();
+            }
+        }
+
+        public List getTypes() {
+            return types;
+        }
+
+        public EditableFeatureType getDefaultType() {
+            return (EditableFeatureType) types.get(0);
+        }
+
+        public void load() throws DataException, CreateEnvelopeException {
+            switch (getDGNParameters().getLoadMode()) {
+            case LOAD_MODE_PLAIN:
+            default:
+                load_plain();
+                break;
+            case LOAD_MODE_GROUP1:
+                load_group1();
+                break;
+            }
+        }
+
+        public void load_plain() throws DataException {
+
+            FileWriter xmlfw = null;
+            BufferedWriter xmlbfw = null;
+
+            this.envelope = null;
+
+            boolean ignoreZs = getDGNParameters().ignoreZs();
+            boolean useZAsElevation = getDGNParameters().useZAsElevation();
+            boolean applyRoundToElevation = getDGNParameters().getApplyRoundToElevation();
+            double elevationFactor = getDGNParameters().geElevationFactor();
+
+            try {
+                if (getDGNParameters().getXMLFile() != null) {
+                    File xmlfile = getDGNParameters().getXMLFile();
+                    try {
+                        xmlfw = new FileWriter(xmlfile);
+                        xmlbfw = new BufferedWriter(xmlfw);
+
+                    } catch (Exception ex) {
+                        xmlfw = null;
+                        xmlbfw = null;
+                        logger.warn("Can't open xmfile for output (" + xmlfile.getAbsolutePath() + "'.", ex);
+                    }
+                    if (xmlbfw != null) {
+                        try {
+                            xmlbfw.write("<DGN>\n");
+                        } catch (IOException ex) {
+                            logger.warn("Can't write to the xml file.", ex);
+                        }
+                    }
+
+                }
+
+                DGNReader dgnReader = new DGNReader(file.getAbsolutePath(), getDGNParameters().logErrors());
+
+                // FIXME: De momento forzamos a que todas las geometr�as que se
+                // creen sean 3D porque el m�todo getFeatureTypes solo puede
+                // crear los geometryAttributes como 3D
+                int subtypeHeader;
+                    subtypeHeader = Geometry.SUBTYPES.GEOM3D;
+
+                envelope = geomManager.createEnvelope(subtypeHeader);
+
+                FeatureType type = getDefaultType().getNotEditableCopy();
+
+                int counterOfElement = 0;
+                DGNElemComplexHeader parentElement = null;
+
+                double zvalue = 0;
+
+                for (int id = 0; id < dgnReader.getNumEntities(); id++) {
+                    dgnReader.DGNGotoElement(id);
+
+                    DGNElemCore elemento = dgnReader.DGNReadElement();
+                    if (elemento == null) {
+                        continue;
+                    }
+
+                    if (parentElement != null) {
+                        counterOfElement++;
+                        if (parentElement.getNumElements() < counterOfElement) {
+                            // Ya hemos terminado de recorrer el elemento complejo.
+                            parentElement = null;
+                        }
+                    }
+
+                    if (xmlbfw != null) {
+                        // Volcamos el elemnto del DGN a fichero en formato XML
+                        try {
+                            xmlbfw.write(dgnReader.DGNDumpElement(dgnReader.getInfo(), elemento));
+                        } catch (IOException ex) {
+                            logger.warn("Can't write to the xml file.", ex);
+                        }
+                    }
+
+                    if (elemento.isDeleted()) {
+                        // Saltamos los elementos borrados.
+                        continue;
+                    }
+
+                    FeatureProvider data = createFeatureProvider(type);
+
+                    data.set(ID_FIELD_ID, elemento.getID());
+                    data.set(ID_FIELD_TYPE, elemento.getType());
+                    data.set(ID_FIELD_STYPE, elemento.getSType());
+                    data.set(ID_FIELD_LEVEL, elemento.getLevelAsString());
+                    data.set(ID_FIELD_COLOR, elemento.getColor());
+                    data.set(ID_FIELD_FILLCOLOR, elemento.getShapeFillColor());
+                    data.set(ID_FIELD_ENTITY, elemento.getEntityName());
+                    data.set(ID_FIELD_STYLE, elemento.getStyle());
+                    data.set(ID_FIELD_WEIGHT, elemento.getWeight());
+                    data.set(ID_FIELD_GROUP, elemento.getGroup());
+                    data.set(ID_FIELD_ELEVATION, elemento.getElevation());
+                    data.set(ID_FIELD_ISCOMPLEXSHAPEHEADER,elemento.isComplexShapeHeader());
+                    data.set(ID_FIELD_ISSHAPE, elemento.isShape());
+                    data.set(ID_FIELD_ISHOLE, elemento.isHole());
+                    data.set(ID_FIELD_ISCOMPLEX, elemento.isComplex());
+                    data.set(ID_FIELD_HEIGHTTEXT, 0);
+                    data.set(ID_FIELD_HEIGHTTEXTRAW, 0);
+                    data.set(ID_FIELD_ROTATIONTEXT, 0);
+                    data.set(ID_FIELD_TEXT, null);
+                    data.set(ID_FIELD_SCALE, dgnReader.getInfo().scale);
+                    data.set(ID_FIELD_DATA, elemento.getDataAsHexadecimal());
+
+                    if (parentElement == null) {
+                        data.set(ID_FIELD_PARENT, elemento.getID());
+                    } else {
+                        data.set(ID_FIELD_PARENT, parentElement.getID());
+                    }
+                    data.set(ID_FIELD_LINKS_COUNT,dgnReader.DGNGetLinkageCount(elemento));
+
+                    DGNLink dgnlink = dgnReader.DGNGetLinkage(elemento,
+                    	getDGNParameters().getLinkFilterIndex(),
+                    	getDGNParameters().getLinkFilterType(),
+                    	getDGNParameters().getLinkFilterEntity(),
+                    	getDGNParameters().getLinkFilterMS(),
+                    	getDGNParameters().getLinkFilterDataAsPattern()
+                    );
+                    if (dgnlink != null) {
+                        data.set(ID_FIELD_LINK_INDEX, dgnlink.getIndex());
+                        data.set(ID_FIELD_LINK_TYPE, dgnlink.getType());
+                        data.set(ID_FIELD_LINK_ENTITY, dgnlink.getEntityCode());
+                        data.set(ID_FIELD_LINK_MS, dgnlink.getMSLink());
+                        data.set(ID_FIELD_LINK_LENGTH, dgnlink.getLength());
+                        data.set(ID_FIELD_LINK_DATA,dgnlink.getDataAsHexadecimal());
+                    } else {
+                        data.set(ID_FIELD_LINK_INDEX, -1);
+                        data.set(ID_FIELD_LINK_TYPE, 0);
+                        data.set(ID_FIELD_LINK_ENTITY, 0);
+                        data.set(ID_FIELD_LINK_MS, 0);
+                        data.set(ID_FIELD_LINK_LENGTH, 0);
+                        data.set(ID_FIELD_LINK_DATA, "");
+                    }
+
+                    zvalue = 0;
+                    try {
+                        int subtypeElement;
+                        switch (elemento.stype) {
+                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
+                            parentElement = (DGNElemComplexHeader) elemento;
+                            counterOfElement = 0;
+                            break;
+
+                        case DGNFileHeader.DGNST_MULTIPOINT:
+                            DGNElemMultiPoint dgnmultipoint = (DGNElemMultiPoint) elemento;
+                            if (dgnmultipoint.isPoint()) {
+                                DGNPoint p = dgnmultipoint.getPoint(0);
+                                Point point = createPoint(p.getX(), p.getY(), ignoreZs ? 0 : p.getZ());
+                                data.setDefaultGeometry(point);
+                                zvalue = p.getZ();
+                            } else {
+                                OrientablePrimitive geom = null;
+                                subtypeElement = getGeometrySubType(dgnmultipoint);
+                                if (dgnmultipoint.isPolygon()) {
+                                    geom = geomManager.createPolygon(subtypeHeader);
+                                } else {
+                                    geom = geomManager.createLine(subtypeHeader);
+                                }
+
+                                // Si es una curva nos saltamos los dos primeros y los dos ultimos vertices.
+                                int first = 0;
+                                int numVertices = dgnmultipoint.getNumVertices();
+                                if (dgnmultipoint.isCurve()) {
+                                    first = 2;
+                                    numVertices = dgnmultipoint.getNumVertices() - 2;
+                                }
+
+                                if (dgnmultipoint.isHole()) {
+                                    // Invertimos el orden porque es un agujero
+                                    for (int i = numVertices - 2; i >= first; i--) {
+                                        DGNPoint p = dgnmultipoint.getVertex(i);
+                                        zvalue = p.getZ();
+                                        addVertex(geom, p.getX(), p.getY(), ignoreZs ? 0 : zvalue);
+                                    }
+                                } else {
+                                    for (int i = first; i < numVertices; i++) {
+                                        DGNPoint p = dgnmultipoint.getVertex(i);
+                                        zvalue = p.getZ();
+                                        addVertex(geom, p.getX(), p.getY(), ignoreZs ? 0 : zvalue);
+                                    }
+                                }
+                                data.setDefaultGeometry(geom);
+                            }
+                            break;
+
+                        case DGNFileHeader.DGNST_ARC:
+                            DGNElemArc dgnarc = (DGNElemArc) elemento;
+
+                            // La definici�n de arco de MicroStation es distinta a la de Java.
+                            // En el dgn el origen se entiende que es el centro del arco,
+                            // y a la hora de crear un Arc2D las 2 primeras coordenadas son
+                            // la esquina inferior izquierda del rect�ngulo que rodea al arco.
+                            // 1.- Creamos la elipse sin rotaci�n.
+                            // 2.- Creamos el arco
+                            // 3.- Rotamos el resultado
+                            AffineTransform mT =
+                                AffineTransform.getRotateInstance(
+                                    Math.toRadians(dgnarc.rotation),
+                                    dgnarc.origin.x, dgnarc.origin.y);
+
+                            Arc2D.Double elArco = new Arc2D.Double(
+                            	dgnarc.origin.x - dgnarc.primary_axis,
+                            	dgnarc.origin.y - dgnarc.secondary_axis,
+                            	2.0 * dgnarc.primary_axis,
+                                2.0 * dgnarc.secondary_axis,
+                                -dgnarc.startang, -dgnarc.sweepang,
+                                Arc2D.OPEN);
+                            
+                            zvalue = dgnarc.origin.getZ();
+
+                            PathIterator pathIterator = elArco.getPathIterator(null);
+                            IGeneralPathX elShapeArc = geomManager.createGeneralPath(
+                                    IGeneralPathX.WIND_EVEN_ODD, 
+                                    pathIterator
+                            );
+
+                            // Transformamos el GeneralPahtX porque si transformamos
+                            // elArco nos lo convierte a GeneralPath y nos guarda las coordenadas en float,
+                            // con la correspondiente p�rdida de precisi�n
+                            elShapeArc.transform(mT);
+
+                            OrientablePrimitive geom = null;
+                            subtypeElement = getGeometrySubType(dgnarc);
+                            if (dgnarc.isSurface()) {
+                                geom = geomManager.createPolygon(subtypeElement);
+                            } else {
+                                geom = geomManager.createLine(subtypeElement);
+                            }
+                            for( int i=0; i<elShapeArc.getNumCoords(); i++ ) {
+                                double[] coords = elShapeArc.getCoordinatesAt(i);
+                                if( ignoreZs || subtypeElement == Geometry.SUBTYPES.GEOM2D || subtypeElement == Geometry.SUBTYPES.GEOM2DM) {
+                                    geom.addVertex(coords[0], coords[1]);
+                                } else {
+                                    geom.addVertex(coords[0], coords[1],zvalue);
+                                }
+                                
+                            }
+                            data.setDefaultGeometry(geom);
+                            break;
+
+                        case DGNFileHeader.DGNST_TEXT:
+                            DGNElemText dgntext = (DGNElemText) elemento;
+                            subtypeElement = getGeometrySubType(dgntext);
+                            Point point = (Point) geomManager.create(TYPES.POINT, subtypeHeader);
+                            point.setCoordinateAt(0, dgntext.getPoint().getX());
+                            point.setCoordinateAt(1, dgntext.getPoint().getY());
+                            if (subtypeHeader == Geometry.SUBTYPES.GEOM3D) {
+                                if(subtypeElement == Geometry.SUBTYPES.GEOM2D){
+                                    point.setCoordinateAt(2, 0);
+                                } else {
+                                    point.setCoordinateAt(2, dgntext.getPoint().getZ());
+                                }
+                            }
+
+                            data.set(ID_FIELD_HEIGHTTEXT, dgntext.getHeight());
+                            data.set(ID_FIELD_HEIGHTTEXTRAW,dgntext.getRawHeight());
+                            data.set(ID_FIELD_ROTATIONTEXT,dgntext.getRotation());
+                            data.set(ID_FIELD_TEXT, dgntext.getText());
+
+                            data.setDefaultGeometry(point);
+                            break;
+
+                        default:
+                            break;
+
+                        } // switch
+                    } catch (Exception ex) {
+                        logger.warn("Can't process element", ex);
+                    }
+                    if (useZAsElevation) {
+                        if (!DGNStoreProvider.equals(elevationFactor, 1, 0.00001)) {
+                            zvalue = zvalue * elevationFactor;
+                        }
+                        if (applyRoundToElevation) {
+                            zvalue = Math.round(zvalue);
+                        }
+                        data.set(ID_FIELD_ELEVATION, zvalue);
+                    }
+                    addFeature(data, dgnReader);
+                } // for
+
+                EditableFeatureType featureType = storeProvider.getFeatureStore().getDefaultFeatureType().getCopy().getEditable();
+                FeatureAttributeDescriptor fad = (FeatureAttributeDescriptor) featureType.get(featureType.getDefaultGeometryAttributeName());
+                featureType.remove(fad.getName());
+                EditableFeatureAttributeDescriptor efad = featureType.add(fad.getName(), fad.getType(), fad.getSize());
+                efad.setDefaultValue(fad.getDefaultValue());
+
+                GeometryType gty = null;
+
+                gty = geomManager.getGeometryType(fad.getGeomType().getType(),subtypeHeader);
+
+                efad.setGeometryType(gty);
+
+                efad.setPrecision(fad.getPrecision());
+                featureType.setDefaultGeometryAttributeName(fad.getName());
+
+
+                if (xmlbfw != null) {
+                    try {
+                        xmlbfw.write("</DGN>\n");
+                    } catch (IOException ex) {
+                        logger.warn("Can't write to the xml file.", ex);
+                    }
+                }
+
+            } catch (Exception ex) {
+                logger.warn("Can't process DGN file '" + getFullName() + ".",ex);
+                throw new LoadException(ex, getFullName());
+            } finally {
+                IOUtils.closeQuietly(xmlbfw);
+                IOUtils.closeQuietly(xmlfw);
+            }
+
+        }
+
+        private int getGeometrySubType(DGNElemCore element) {
+            if (getDGNParameters().force2D()) {
+                return Geometry.SUBTYPES.GEOM2D;
+            }
+            return element.is3D() ? Geometry.SUBTYPES.GEOM3D : Geometry.SUBTYPES.GEOM2D;
+        }
+
+        private void addVertex(OrientablePrimitive geom, double x, double y,
+            double z) {
+            if (geom.getDimension() == 2) {
+                geom.addVertex(x, y);
+            } else {
+                geom.addVertex(x, y, z);
+            }
+        }
+
+        private void fillRow(Object[] row, DGNElemCore elemento, DGNElemComplexHeader parentElement, DGNReader dgnReader) {
+            row[ID_FIELD_HEIGHTTEXT] = new Double(0);
+            row[ID_FIELD_HEIGHTTEXTRAW] = new Double(0);
+            row[ID_FIELD_ROTATIONTEXT] = new Double(0);
+            row[ID_FIELD_TEXT] = null;
+
+            row[ID_FIELD_ID] = elemento.getID();
+            row[ID_FIELD_TYPE] = elemento.getType();
+            row[ID_FIELD_STYPE] = elemento.getSType();
+            row[ID_FIELD_LEVEL] = elemento.getLevelAsString();
+            row[ID_FIELD_COLOR] = elemento.getColor();
+            row[ID_FIELD_FILLCOLOR] = elemento.getShapeFillColor();
+            row[ID_FIELD_ENTITY] = elemento.getEntityName();
+            row[ID_FIELD_STYLE] = elemento.getStyle();
+            row[ID_FIELD_WEIGHT] = elemento.getWeight();
+            row[ID_FIELD_GROUP] = elemento.getGroup();
+            row[ID_FIELD_ELEVATION] = elemento.getElevation();
+            row[ID_FIELD_ISCOMPLEXSHAPEHEADER] = elemento.isComplexShapeHeader();
+            row[ID_FIELD_ISSHAPE] = elemento.isShape();
+            row[ID_FIELD_ISHOLE] = elemento.isHole();
+            row[ID_FIELD_ISCOMPLEX] = elemento.isComplex();
+            row[ID_FIELD_PARENT] = elemento.getID();
+            if (parentElement != null) {
+                row[ID_FIELD_PARENT] = parentElement.getID();
+            }
+            row[ID_FIELD_SCALE] = dgnReader.getInfo().scale;
+
+        }
+
+        public void load_group1() throws DataException, CreateEnvelopeException {
+
+            this.envelope = null;
+
+            FileWriter xmlfw = null;
+            BufferedWriter xmlbfw = null;
+            if (getDGNParameters().getXMLFile() != null) {
+                File xmlfile = getDGNParameters().getXMLFile();
+                try {
+                    xmlfw = new FileWriter(xmlfile);
+                    xmlbfw = new BufferedWriter(xmlfw);
+
+                } catch (Exception ex) {
+                    xmlfw = null;
+                    xmlbfw = null;
+                    logger.warn("Can't open xmfile for output ("+ xmlfile.getAbsolutePath() + "'.", ex);
+                }
+                if (xmlbfw != null) {
+                    try {
+                        xmlbfw.write("<DGN>\n");
+                    } catch (IOException ex) {
+                        logger.warn("Can't write to the xml file.", ex);
+                    }
+                }
+
+            }
+            DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
+            if (dgnReader.getInfo().dimension == 2) {
+                envelope = geomManager.createEnvelope(Geometry.SUBTYPES.GEOM2D);
+            } else {
+                envelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
+            }
+
+            FeatureType type = getDefaultType().getNotEditableCopy();
+            int fTypeSize = type.size();
+            Object[] auxRow = new Object[fTypeSize];
+            Object[] cellRow = new Object[fTypeSize];
+            Object[] complexRow = new Object[fTypeSize];
+
+            boolean bElementoCompuesto = false;
+            boolean bEsPoligono = false;
+            boolean bInsideCell = false;
+            boolean bFirstHoleEntity = false;
+            boolean bConnect = false; // Se usa para que los pol�gonos cierren
+            // bien cuando son formas compuestas
+            // int contadorSubElementos = 0;
+            // int numSubElementos = 0;
+            int complex_index_fill_color = -1;
+            int nClass; // Para filtrar los elementos de construcci�n, etc.
+            IGeneralPathX elementoCompuesto = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
+
+            int counterOfElement = 0;
+            DGNElemComplexHeader parentElement = null;
+
+            for (int id = 0; id < dgnReader.getNumEntities(); id++) {
+                dgnReader.DGNGotoElement(id);
+
+                DGNElemCore elemento = dgnReader.DGNReadElement();
+                if (parentElement != null) {
+                    counterOfElement++;
+                    if (parentElement.getNumElements() < counterOfElement) {
+                        // Ya hemos terminado de recorrer el elemento complejo.
+                        parentElement = null;
+                    }
+                }
+
+                if (xmlbfw != null && elemento != null) {
+                    // Volcamos el elemnto del DGN a fichero en formato XML
+                    try {
+                        xmlbfw.write(dgnReader.DGNDumpElement(dgnReader.getInfo(), elemento));
+                    } catch (IOException ex) {
+                        logger.warn("Can't write to the xml file.", ex);
+                    }
+                }
+
+                nClass = 0;
+                fillRow(auxRow, elemento, parentElement, dgnReader);
+                auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0);
+                auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0);
+                auxRow[ID_FIELD_TEXT] = null;
+
+                if (elemento.properties != 0) {
+                    nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS;
+                }
+
+                if ((elemento != null) && (elemento.deleted == 0)
+                    && (nClass == 0)) // Leer un elemento
+                {
+
+                    // if ((elemento.element_id > 3800) && (elemento.element_id < 3850))
+                    // dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
+                    if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
+                        || (elemento.stype == DGNFileHeader.DGNST_ARC)
+                        || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER)
+                        || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN)
+                        || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) {
+                        if (elemento.complex != 0) {
+                            bElementoCompuesto = true;
+                        } else {
+                            if (bElementoCompuesto) {
+                                if (bInsideCell) {
+                                    auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY];
+                                } else {
+                                    auxRow = complexRow;
+                                }
+                                addShape(createMultiCurve(elementoCompuesto),
+                                    auxRow, type, dgnReader);
+
+                                if (bEsPoligono) {
+                                    if (complex_index_fill_color != -1) {
+                                        auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
+                                    }
+
+                                    addShape(
+                                        createMultiSurface(elementoCompuesto),
+                                        auxRow, type, dgnReader);
+                                }
+
+                                elementoCompuesto = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
+                            }
+
+                            bElementoCompuesto = false;
+                            bEsPoligono = false;
+                            bConnect = false;
+
+                            bInsideCell = false;
+                        }
+                    }
+
+                    switch (elemento.stype) {
+                    case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
+                        bInsideCell = true;
+                        fillRow(cellRow, elemento, parentElement, dgnReader);
+                        cellRow[ID_FIELD_ID] = elemento.element_id;
+                        cellRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        cellRow[ID_FIELD_COLOR] = elemento.color;
+                        cellRow[ID_FIELD_ENTITY] = "Shared Cell";
+
+                        break;
+
+                    case DGNFileHeader.DGNST_CELL_HEADER:
+                        bInsideCell = true;
+
+                        fillRow(cellRow, elemento, parentElement, dgnReader);
+                        cellRow[ID_FIELD_ID] = elemento.element_id;
+                        cellRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        cellRow[ID_FIELD_COLOR] = elemento.color;
+                        cellRow[ID_FIELD_ENTITY] = "Cell";
+                        complex_index_fill_color = dgnReader.DGNGetShapeFillInfo(elemento);
+                        break;
+
+                    case DGNFileHeader.DGNST_COMPLEX_HEADER:
+
+                        // bElementoCompuesto = true;
+                        // contadorSubElementos = 0;
+                        DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento;
+
+                        parentElement = psComplexHeader;
+                        counterOfElement = parentElement.getNumElements();
+
+                        // numSubElementos = psComplexHeader.numelems;
+                        fillRow(complexRow, elemento, parentElement, dgnReader);
+                        complexRow[ID_FIELD_ID] = elemento.element_id;
+                        complexRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        complexRow[ID_FIELD_COLOR] = elemento.color;
+                        complexRow[ID_FIELD_ENTITY] = "Complex";
+
+                        if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
+                            bEsPoligono = true;
+
+                            // Si es un agujero, no conectamos con el anterior
+                            if ((psComplexHeader.properties & 0x8000) != 0) {
+                                bFirstHoleEntity = true;
+                            } else {
+                                // Miramos si tiene color de relleno
+                                // complex_index_fill_color = -1;
+                                // if (elemento.attr_bytes > 0) {
+                                complex_index_fill_color = dgnReader.DGNGetShapeFillInfo(elemento);
+
+                                // }
+                            }
+
+                            bConnect = true;
+                        } else {
+                            bEsPoligono = false;
+                            bConnect = false;
+                        }
+
+                        break;
+
+                    case DGNFileHeader.DGNST_MULTIPOINT:
+
+                        // OJO: Si lo que viene en este multipoint es un
+                        // elemento con type=11 (curve), se trata de una "parametric
+                        // spline curve". La vamos a tratar como si no fuera
+                        // curva, pero seg�n la documentaci�n, los 2 primeros puntos
+                        // y los 2 �ltimos puntos definen "endpoint derivatives" y NO se muestran.
+                        // TODAV�A HAY UN PEQUE�O FALLO CON EL FICHERO
+                        // dgn-sample.dgn, pero lo dejo por ahora.
+                        // Es posible que tenga que ver con lo de los arcos
+                        // (arco distorsionado), que todav�a no est� metido.
+                        DGNElemMultiPoint psLine = (DGNElemMultiPoint) elemento;
+                        fillRow(auxRow, elemento, parentElement, dgnReader);
+                        auxRow[ID_FIELD_ID] = elemento.element_id;
+                        auxRow[ID_FIELD_ENTITY] = "Multipoint";
+                        auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        auxRow[ID_FIELD_COLOR] = elemento.color;
+
+                        if ((psLine.num_vertices == 2)
+                            && (psLine.vertices[0].x == psLine.vertices[1].x)
+                            && (psLine.vertices[0].y == psLine.vertices[1].y)) {
+                            auxRow[ID_FIELD_ENTITY] = "Point";
+                            addShape(
+                                createPoint(psLine.vertices[0].x,
+                                    psLine.vertices[0].y,
+                                    psLine.vertices[0].z),
+                                auxRow,
+                                type, dgnReader);
+                        } else {
+                            IGeneralPathX elShape = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
+
+                            if (psLine.type == DGNFileHeader.DGNT_CURVE) {
+                                psLine.num_vertices = psLine.num_vertices - 4;
+
+                                for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) {
+                                    psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
+                                }
+                            }
+
+                            if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
+                                && ((psLine.properties & 0x8000) != 0)) {
+                                // Invertimos el orden porque es un agujero
+                                elShape.moveTo(
+                                    psLine.vertices[psLine.num_vertices - 1].x,
+                                    psLine.vertices[psLine.num_vertices - 1].y);
+
+                                for (int i = psLine.num_vertices - 2; i >= 0; i--) {
+                                    elShape.lineTo(psLine.vertices[i].x,
+                                        psLine.vertices[i].y);
+                                }
+                            } else {
+                                elShape.moveTo(psLine.vertices[0].x,
+                                    psLine.vertices[0].y);
+
+                                for (int i = 1; i < psLine.num_vertices; i++) {
+                                    elShape.lineTo(psLine.vertices[i].x,
+                                        psLine.vertices[i].y);
+                                }
+                            }
+
+                            if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x)
+                                && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) {
+                                // Lo a�adimos tambi�n como pol�gono
+                                bEsPoligono = true;
+
+                                // Miramos si tiene color de relleno
+                                if (elemento.attr_bytes > 0) {
+                                    elemento.color = dgnReader.DGNGetShapeFillInfo(elemento);
+
+                                    if (elemento.color != -1) {
+                                        auxRow[ID_FIELD_COLOR] = elemento.color;
+                                    }
+                                }
+
+                                if (elemento.complex == 0) {
+                                    addShape(createSurface(elShape), auxRow,
+                                        type, dgnReader);
+                                }
+                            }
+
+                            if (elemento.complex != 0) {
+                                // Si es un agujero o
+                                // es la primera entidad del agujero, lo
+                                // a�adimos sin unir al anterior
+                                if (bFirstHoleEntity
+                                    || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) {
+                                    elementoCompuesto.append(elShape.getPathIterator(null), false);
+                                    bFirstHoleEntity = false;
+                                } else {
+                                    elementoCompuesto.append(elShape.getPathIterator(null),
+                                            bConnect);
+                                }
+                            } else {
+                                addShape(createMultiCurve(elShape), auxRow,
+                                    type, dgnReader);
+                            }
+                        }
+
+                        break;
+
+                    case DGNFileHeader.DGNST_ARC:
+
+                        // dgnReader.DGNDumpElement(dgnReader.getInfo(),
+                        // elemento,"");
+                        DGNElemArc psArc = (DGNElemArc) elemento;
+
+                        // La definici�n de arco de MicroStation es distinta a
+                        // la de Java.
+                        // En el dgn el origin se entiende que es el centro del
+                        // arco,
+                        // y a la hora de crear un Arc2D las 2 primeras
+                        // coordenadas son
+                        // la esquina inferior izquierda del rect�ngulo que
+                        // rodea al arco.
+                        // 1.- Creamos la elipse sin rotaci�n.
+                        // 2.- Creamos el arco
+                        // 3.- Rotamos el resultado
+                        AffineTransform mT = AffineTransform.getRotateInstance(
+                                Math.toRadians(psArc.rotation), psArc.origin.x,
+                                psArc.origin.y);
+
+                        // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
+                        Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x
+                                - psArc.primary_axis, psArc.origin.y
+                                - psArc.secondary_axis,
+                                2.0 * psArc.primary_axis,
+                                2.0 * psArc.secondary_axis, -psArc.startang,
+                                -psArc.sweepang, Arc2D.OPEN);
+
+                        // Ellipse2D.Double elArco = new
+                        // Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
+                        // psArc.origin.y - psArc.secondary_axis,2.0 *
+                        // psArc.primary_axis, 2.0 * psArc.secondary_axis);
+                        IGeneralPathX elShapeArc = geomManager.createGeneralPath(
+                                IGeneralPathX.WIND_EVEN_ODD, 
+                                elArco.getPathIterator(null)
+                        );
+
+                        // Transformamos el GeneralPahtX porque si transformamos
+                        // elArco nos lo convierte
+                        // a GeneralPath y nos guarda las coordenadas en float,
+                        // con la correspondiente p�rdida de precisi�n
+                        elShapeArc.transform(mT);
+
+                        if (dgnReader.getInfo().dimension == 3) {
+                            // Aqu� podr�amos hacer cosas con la coordenada Z
+                        }
+
+                        fillRow(auxRow, elemento, parentElement, dgnReader);
+                        auxRow[ID_FIELD_ID] = elemento.element_id;
+                        auxRow[ID_FIELD_ENTITY] = "Arc";
+                        auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        auxRow[ID_FIELD_COLOR] = elemento.color;
+
+                        /*
+                         * Line2D.Double ejeMayor = new
+                         * Line2D.Double(psArc.origin.x - psArc.primary_axis,
+                         * psArc.origin.y, psArc.origin.x + psArc.primary_axis,
+                         * psArc.origin.y);
+                         *
+                         * lyrLines.addShape(new
+                         * FShape(FConstant.SHAPE_TYPE_POLYLINE, new
+                         * GeneralPathX(ejeMayor)), auxRow);
+                         */
+                        // lyrLines.addShape(new
+                        // FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
+                        // auxRow);
+                        if (elemento.complex != 0) {
+                            // Esto es una posible fuente de fallos si detr�s de
+                            // una elipse vienen m�s cosas pegadas. Deber�amos
+                            // volver a conectar una vez pasada la elipse.
+                            if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
+                                bConnect = false;
+                            }
+
+                            // SI LA ELIPSE ES UN AGUJERO, SE A�ADE SIN PEGAR
+                            // Y EL ELEMENTO ES UN POLIGONO
+                            if (bFirstHoleEntity
+                                || ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) {
+                                elementoCompuesto.append(elShapeArc.getPathIterator(null), false);
+                                bFirstHoleEntity = false;
+                            } else {
+                                elementoCompuesto.append(elShapeArc.getPathIterator(null), bConnect);
+                            }
+                        } else {
+                            addShape(createMultiCurve(elShapeArc), auxRow,
+                                type, dgnReader);
+
+                            if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
+                                addShape(createSurface(elShapeArc), auxRow,
+                                    type, dgnReader);
+                            }
+                        }
+
+                        break;
+
+                    case DGNFileHeader.DGNST_TEXT:
+
+                        DGNElemText psText = (DGNElemText) elemento;
+                        Geometry elShapeTxt = createPoint(psText.origin.x, psText.origin.y,
+                                psText.origin.z);
+
+                        fillRow(auxRow, elemento, parentElement, dgnReader);
+                        auxRow[ID_FIELD_ID] = elemento.element_id;
+                        auxRow[ID_FIELD_ENTITY] = "Text";
+                        auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
+                        auxRow[ID_FIELD_COLOR] = elemento.color;
+                        auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult;
+                        auxRow[ID_FIELD_HEIGHTTEXTRAW] = psText.height_raw;
+                        auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation;
+                        auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
+                        addShape(elShapeTxt, auxRow, type, dgnReader);
+                        break;
+
+                    /*
+                     * default:
+                     * dgnReader.DGNDumpElement(dgnReader.getInfo(),
+                     * elemento, "");
+                     */
+                    } // switch
+                } // if
+            } // for
+
+            if (bElementoCompuesto) {
+                if (bInsideCell) {
+                    auxRow = cellRow;
+                } else {
+                    auxRow = complexRow;
+                }
+
+                addShape(createMultiCurve(elementoCompuesto), auxRow, type,
+                    dgnReader);
+
+                if (bEsPoligono) {
+                    if (complex_index_fill_color != -1) {
+                        auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
+                    }
+
+                    addShape(createSurface(elementoCompuesto), auxRow, type,
+                        dgnReader);
+                }
+            }
+
+            if (xmlbfw != null) {
+                try {
+                    xmlbfw.write("</DGN>\n");
+                } catch (IOException ex) {
+                    logger.warn("Can't write to the xml file.", ex);
+                }
+                IOUtils.closeQuietly(xmlbfw);
+                IOUtils.closeQuietly(xmlfw);
+            }
+
+        }
+
+        private Geometry createMultiSurface(IGeneralPathX elementoCompuesto)
+            throws DataException {
+            try {
+                return geomManager.createMultiSurface(
+                        (GeneralPathX) elementoCompuesto,
+                        SUBTYPES.GEOM2D
+                );
+            } catch (CreateGeometryException e) {
+                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
+                    e);
+            }
+
+        }
+
+        private Point createPoint(double x, double y, double z)
+            throws DataException {
+            Point point;
+            int subtype = SUBTYPES.GEOM3D;
+            if (getDGNParameters().force2D()) {
+                subtype = SUBTYPES.GEOM2D;
+            }
+            try {
+                point = (Point) geomManager.create(TYPES.POINT, subtype);
+            } catch (CreateGeometryException e) {
+                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
+            }
+            point.setCoordinates(new double[] { x, y, z });
+
+            return point;
+        }
+
+        private void addFeature(FeatureProvider data, DGNReader dgnReader) throws DataException {
+
+            addFeatureProvider(data);
+            Geometry geometry = data.getDefaultGeometry();
+            if (geometry != null) {
+                if (this.envelope == null) {
+                    this.envelope = geometry.getEnvelope();
+                } else {
+                    this.envelope.add(geometry.getEnvelope());
+                }
+            }
+            if (this.leyendBuilder != null) {
+                this.leyendBuilder.process(data, dgnReader);
+            }
+        }
+
+        private void addShape(Geometry geometry, Object[] auxRow,
+            FeatureType type, DGNReader dgnReader) throws DataException {
+
+            FeatureProvider data = createFeatureProvider(type);
+            for (int i = 0; i < type.size(); i++) {
+                data.set(i, auxRow[i]);
+            }
+            data.setDefaultGeometry(geometry);
+            addFeature(data, dgnReader);
+        }
+
+        private Geometry createMultiCurve(IGeneralPathX elementoCompuesto)
+            throws DataException {
+            try {
+                return geomManager.createMultiCurve((GeneralPathX) elementoCompuesto,
+                    SUBTYPES.GEOM2D);
+            } catch (CreateGeometryException e) {
+                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
+                    e);
+            }
+        }
+
+        private Geometry createSurface(IGeneralPathX elementoCompuesto)
+            throws DataException {
+            try {
+                return geomManager.createCurve((GeneralPathX) elementoCompuesto,
+                    SUBTYPES.GEOM2D);
+            } catch (CreateGeometryException e) {
+                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
+                    e);
+            }
+
+        }
+
+    }
+
+    public boolean closeResourceRequested(ResourceProvider resource) {
+        return true;
+    }
+
+    public int getOIDType() {
+        return DataTypes.LONG;
+    }
+
+    public boolean supportsAppendMode() {
+        return false;
+    }
+
+    public void append(FeatureProvider featureProvider) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void beginAppend() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void endAppend() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object createNewOID() {
+        return new Long(counterNewsOIDs++);
+    }
+
+    protected void initializeFeatureTypes() throws InitializeException {
+        try {
+            this.open();
+        } catch (OpenException e) {
+            throw new InitializeException(this.getProviderName(), e);
+        }
+    }
+
+    public Envelope getEnvelope() throws DataException {
+        this.open();
+        return (Envelope) this.getDynValue("Envelope");
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
+     * gvsig.fmap.dal.resource.spi.ResourceProvider)
+     */
+    public void resourceChanged(ResourceProvider resource) {
+        this.getStoreServices().notifyChange(
+            DataStoreNotification.RESOURCE_CHANGED, resource);
+    }
+
+    public Object getSourceId() {
+        return this.getDGNParameters().getFile();
+    }
+
+    public String getName() {
+        String name = this.getDGNParameters().getFile().getName();
+        int n = name.lastIndexOf(".");
+        if (n < 1) {
+            return name;
+        }
+        return name.substring(0, n);
+    }
+
+    public String getFullName() {
+        return this.getDGNParameters().getFile().getAbsolutePath();
+    }
+
+    public ResourceProvider getResource() {
+        return resource;
+    }
+
+    public static boolean equals(double a, double b, double precision) {
+        double v = Math.abs(a - b);
+        return v < precision;
+    }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessGroupOperation.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessGroupOperation.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessGroupOperation.java	(revision 509)
@@ -0,0 +1,309 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.gvsig.fmap.dal.feature.FeatureType;
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_CONVEXHULL;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_INTERSECTION;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_NONE;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_TOLINES;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_TOPOINTS;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_TOPOLYGONS;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_TOPOLYGONS_FIX;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.GROUP_GEOMETRIES_UNION;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.fmap.geom.GeometryLocator;
+import org.gvsig.fmap.geom.GeometryManager;
+import org.gvsig.fmap.geom.aggregate.Aggregate;
+import org.gvsig.fmap.geom.aggregate.MultiLine;
+import org.gvsig.fmap.geom.aggregate.MultiPolygon;
+import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
+import org.gvsig.fmap.geom.exception.CreateGeometryException;
+import org.gvsig.fmap.geom.primitive.Curve;
+import org.gvsig.fmap.geom.primitive.Envelope;
+import org.gvsig.fmap.geom.primitive.Line;
+import org.gvsig.fmap.geom.primitive.Point;
+import org.gvsig.fmap.geom.primitive.Polygon;
+import org.gvsig.fmap.geom.primitive.Primitive;
+import org.gvsig.fmap.geom.primitive.Surface;
+import org.gvsig.tools.logger.FilteredLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PostProcessGroupOperation {
+
+    private static final Logger logger = LoggerFactory.getLogger(PostProcessGroupOperation.class);
+
+    private int groupByFieldIndex = -1;
+    private Map<Object, FeatureProvider> groupedFeatures = null;
+    private GeometryManager geomManager = null;
+    private int ID_FIELD_GEOMETRY = -1;
+    private int MAX_FIELD_ID = -1;
+    private int groupGeometriesOperation = -1;
+    private Envelope envelope = null;
+
+    public PostProcessGroupOperation(FeatureType featureType, String groupfield, int groupGeometriesOperation) {
+        this.groupByFieldIndex = featureType.getIndex(groupfield);
+        if (groupByFieldIndex < 0) {
+            throw new IllegalArgumentException("Can't group by field '" + groupfield + ", the field don't exists.");
+        }
+        this.geomManager = GeometryLocator.getGeometryManager();
+        this.ID_FIELD_GEOMETRY = featureType.getDefaultGeometryAttribute().getIndex();
+        this.MAX_FIELD_ID = featureType.size() - 1;
+        this.groupGeometriesOperation = groupGeometriesOperation;
+    }
+
+    public void add(FeatureProvider data) {
+        if (groupedFeatures == null) {
+            groupedFeatures = new HashMap<Object, FeatureProvider>();
+        }
+        Object groupbyValue = data.get(groupByFieldIndex);
+        FeatureProvider group = groupedFeatures.get(groupbyValue);
+        if (group == null) {
+            groupedFeatures.put(groupbyValue, data);
+            MultiPrimitive multi = getMultiPrimitive((Geometry) data.get(ID_FIELD_GEOMETRY));
+            if (multi == null) {
+                data.set(ID_FIELD_GEOMETRY, null);
+            } else {
+                data.set(ID_FIELD_GEOMETRY, multi);
+            }
+            return;
+        }
+        for (int i = 0; i <= MAX_FIELD_ID; i++) {
+            Object value = group.get(i);
+            if (i == ID_FIELD_GEOMETRY) {
+                Geometry newgeom = (Geometry) data.get(i);
+                if (newgeom != null) {
+                    if (value == null) {
+                        group.set(ID_FIELD_GEOMETRY, getMultiPrimitive(newgeom));
+                    } else {
+                        try {
+                            ((MultiPrimitive) value).addPrimitive((Primitive) newgeom);
+                        } catch (Exception ex) {
+                            logger.warn("Can't group geoemtry '" + newgeom.toString() + "' in '" + value.toString() + "'.", ex);
+                        }
+                    }
+                }
+            } else if (value == null) {
+                group.set(i, data.get(i));
+            } else if (value instanceof String) {
+                String s = (String) value;
+                if (s.trim().length() == 0) {
+                    group.set(i, data.get(i));
+                }
+            }
+        }
+
+    }
+
+    private MultiPrimitive getMultiPrimitive(Geometry geom) {
+        if (geom == null) {
+            return null;
+        }
+        if (geom instanceof MultiPrimitive) {
+            return (MultiPrimitive) geom;
+        }
+        MultiPrimitive multi = null;
+        try {
+            if (geom instanceof Point) {
+                multi = (MultiPrimitive) geomManager.create(
+                        Geometry.TYPES.MULTIPOINT,
+                        geom.getGeometryType().getSubType()
+                );
+            } else if (geom instanceof Curve) {
+                multi = (MultiPrimitive) geomManager.create(
+                        Geometry.TYPES.MULTICURVE,
+                        geom.getGeometryType().getSubType()
+                );
+            } else if (geom instanceof Surface) {
+                multi = (MultiPrimitive) geomManager.create(
+                        Geometry.TYPES.MULTISURFACE,
+                        geom.getGeometryType().getSubType()
+                );
+            }
+            if (multi != null) {
+                multi.addPrimitive((Primitive) geom);
+            }
+        } catch (CreateGeometryException ex) {
+            logger.warn("Can't create multi-geometry to group", ex);
+        }
+        return multi;
+    }
+
+    public List<FeatureProvider> getRows() {
+        if (this.groupGeometriesOperation < 0) {
+            Iterator<FeatureProvider> rowsIterator = this.groupedFeatures.values().iterator();
+            while( rowsIterator.hasNext() ) {
+                FeatureProvider feature = rowsIterator.next();
+                Geometry geometry = feature.getDefaultGeometry();
+                if (geometry != null) {
+                    if (this.envelope == null) {
+                        this.envelope = geometry.getEnvelope();
+                    } else {
+                        this.envelope.add(geometry.getEnvelope());
+                    }
+                }
+            }
+            return (List<FeatureProvider>) this.groupedFeatures.values();
+        }
+
+        List<FeatureProvider> result = new ArrayList<FeatureProvider>();
+        
+        FilteredLogger log = new FilteredLogger(logger, "ConsolideGroupBy", 10);
+
+        Iterator<Map.Entry<Object, FeatureProvider>> it = groupedFeatures.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<Object, FeatureProvider> entry = it.next();
+            String groupValue = "<null>";
+            if (entry.getKey() != null) {
+                groupValue = entry.getKey().toString();
+            }
+            try {
+                FeatureProvider data = entry.getValue();
+                Geometry geometry = data.getDefaultGeometry();
+                if (geometry != null) {
+                    switch (this.groupGeometriesOperation) {
+                        case GROUP_GEOMETRIES_NONE:
+                            break;
+                        case GROUP_GEOMETRIES_CONVEXHULL:
+                            try {
+                                geometry = geometry.convexHull();
+                                data.set(ID_FIELD_GEOMETRY, geometry);
+                            } catch (Exception ex) {
+                                log.warn("Can't create convex-hull with geometries of the group '" + groupValue + "'.", ex);
+                            }
+                            break;
+                        case GROUP_GEOMETRIES_UNION:
+                            if (geometry instanceof Aggregate) {
+                                try {
+                                    geometry = ((Aggregate) geometry).union();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+                                } catch (Exception ex) {
+                                    log.warn("Can't create a union with geometries of the group '" + groupValue + "'.", ex);
+                                }
+                            }
+                            break;
+                        case GROUP_GEOMETRIES_INTERSECTION:
+                            if (geometry instanceof Aggregate) {
+                                try {
+                                    geometry = ((Aggregate) geometry).intersection();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+                                } catch (Exception ex) {
+                                    log.warn("Can't create a intersection with geometries of the group '" + groupValue + "'.", ex);
+                                }
+                            }
+                            break;
+
+                        case GROUP_GEOMETRIES_TOPOINTS:
+                            try {
+                                if (geometry instanceof Line) {
+                                    geometry = ((Line) geometry).toPoints();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof Polygon) {
+                                    geometry = ((Polygon) geometry).toPoints();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof Point) {
+                                    geometry = ((Point) geometry).toPoints();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof MultiLine) {
+                                    geometry = ((MultiLine) geometry).toPoints();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof MultiPolygon) {
+                                    geometry = ((MultiPolygon) geometry).toPoints();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                }
+                            } catch (Exception ex) {
+                                log.warn("Can't convert to points the geometries of the group '" + groupValue + "'.", ex);
+                            }
+                            break;
+
+                        case GROUP_GEOMETRIES_TOLINES:
+                            try {
+                                if (geometry instanceof Polygon) {
+                                    geometry = ((Polygon) geometry).toLines();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof MultiPolygon) {
+                                    geometry = ((MultiPolygon) geometry).toLines();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                }
+                            } catch (Exception ex) {
+                                log.warn("Can't convert to lines the geometries of the group '" + groupValue + "'.", ex);
+                            }
+                            break;
+
+                        case GROUP_GEOMETRIES_TOPOLYGONS:
+                            try {
+                                if (geometry instanceof Line) {
+                                    geometry = ((Line) geometry).toPolygons();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof MultiLine) {
+                                    geometry = ((MultiLine) geometry).toPolygons();
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else {
+                                    geometry = null;
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+                                }
+                            } catch (Exception ex) {
+                                log.warn("Can't convert to polygons the geometries of the group '" + groupValue + "'.", ex);
+                            }
+                            break;
+
+                        case GROUP_GEOMETRIES_TOPOLYGONS_FIX:
+                            try {
+                                if (geometry instanceof Line) {
+                                    geometry = ((Line) geometry).toPolygons();
+                                    geometry = geometry.buffer(0);
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else if (geometry instanceof MultiLine) {
+                                    geometry = ((MultiLine) geometry).toPolygons();
+                                    geometry = geometry.buffer(0);
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+
+                                } else {
+                                    geometry = null;
+                                    data.set(ID_FIELD_GEOMETRY, geometry);
+                                }
+                            } catch (Exception ex) {
+                                log.warn("Can't convert to polygons the geometries of the group '" + groupValue + "'.", ex);
+                            }
+                            break;
+                    }
+                    if (geometry != null) {
+                        if (this.envelope == null) {
+                            this.envelope = geometry.getEnvelope();
+                        } else {
+                            this.envelope.add(geometry.getEnvelope());
+                        }
+                    }
+                }
+                result.add(data);
+            } catch (Exception ex) {
+                log.warn("Problem adding data from group '" + groupValue + "'.", ex);
+            }
+        }
+        return result;
+    }
+
+    public Envelope getEnvelope() {
+        if( this.envelope == null ) {
+            
+        }
+        return this.envelope;
+    }
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFeatures.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFeatures.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFeatures.java	(revision 509)
@@ -0,0 +1,168 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import org.gvsig.fmap.dal.feature.FeatureType;
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.TimeCounter;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.fmap.geom.GeometryLocator;
+import org.gvsig.fmap.geom.GeometryManager;
+import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
+import org.gvsig.fmap.geom.primitive.Envelope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PostProcessFeatures {
+
+    private static final Logger logger = LoggerFactory.getLogger(PostProcessFeatures.class);
+
+    private final FeatureType featureType;
+    private final DGNOpenStoreParameters parameters;
+    private Envelope envelope;
+    private final int geomSubtype;
+    private PostProcessFilterOperation filter = null;
+
+    public PostProcessFeatures(DGNOpenStoreParameters parameters, FeatureType featureType) {
+        this.featureType = featureType;
+        this.parameters = parameters;
+        if (parameters.ignoreZs()) {
+            this.geomSubtype = Geometry.SUBTYPES.GEOM2D;
+        } else {
+            this.geomSubtype = featureType.getDefaultGeometryAttribute().getGeomType().getSubType();
+        }
+    }
+
+    private DGNOpenStoreParameters getDGNParameters() {
+        return this.parameters;
+    }
+
+    private PostProcessFilterOperation getFilter() {
+        if (this.filter == null) {
+            this.filter = new PostProcessFilterOperation(
+                    getDGNParameters(),
+                    featureType
+            );
+        }
+        return this.filter;
+    }
+
+    public List<FeatureProvider> apply(List<FeatureProvider> rows) throws CreateEnvelopeException {
+
+        TimeCounter tc_total = new TimeCounter();
+        TimeCounter tc_accept = new TimeCounter();
+
+        PostProcessFilterOperation filter = this.getFilter();
+
+        List<FeatureProvider> result = null;
+
+        Iterator<FeatureProvider> rowsIterator = rows.iterator();
+
+        int rowCount = 0;
+        int rowFitereds = 0;
+        if (parameters.getGroupBy() == null) {
+            GeometryManager geomManager = GeometryLocator.getGeometryManager();
+            this.envelope = geomManager.createEnvelope(this.geomSubtype);
+
+            tc_total.start();
+            result = new ArrayList<FeatureProvider>();
+            while (rowsIterator.hasNext()) {
+                FeatureProvider feature = rowsIterator.next();
+                rowCount++;
+
+                tc_accept.start();
+                boolean accept = filter.accept(feature);
+                tc_accept.stop();
+
+                if (!accept) {
+                    continue;
+                }
+                rowFitereds++;
+                Geometry geom = feature.getDefaultGeometry();
+                if (geom != null) {
+                    this.envelope.add(geom.getEnvelope());
+                }
+                result.add(feature);
+            }
+            tc_total.stop();
+            tc_accept.log("Accepts time filter");
+            tc_total.log("Total time filer, rows input "+rowCount+", output "+rowFitereds );
+
+        } else {
+            tc_total.start();
+
+            PostProcessGroupOperation groupOperation = new PostProcessGroupOperation(
+                    this.featureType,
+                    parameters.getGroupBy(),
+                    parameters.getGroupGeometriesOperation()
+            );
+            while (rowsIterator.hasNext()) {
+                FeatureProvider feature = rowsIterator.next();
+                rowCount++;
+
+                tc_accept.start();
+                boolean accept = filter.accept(feature);
+                tc_accept.stop();
+
+                if (!accept) {
+                    continue;
+                }
+                rowFitereds++;
+                groupOperation.add(feature);
+            }
+            result = groupOperation.getRows();
+            this.envelope = groupOperation.getEnvelope();
+
+            tc_total.stop();
+            tc_accept.log("Accepts time filter+group");
+            tc_total.log("Total time filer+group, rows input "+rowCount+", output "+rowFitereds );
+        }
+
+        if (parameters.sortByGeometryType()) {
+            this.sortRows(result);
+        }
+        return result;
+    }
+
+    public Envelope getEnvelope() {
+        return this.envelope;
+    }
+
+    private void sortRows(List<FeatureProvider> rows) {
+        TimeCounter tc = new TimeCounter();
+        tc.start();
+        Collections.sort(rows, new Comparator<FeatureProvider>() {
+            public int compare(FeatureProvider o1, FeatureProvider o2) {
+                Geometry g1 = o1.getDefaultGeometry();
+                Geometry g2 = o2.getDefaultGeometry();
+                if (g1 == null) {
+                    if (g2 == null) {
+                        return 0;
+                    } else {
+                        return -1;
+                    }
+                } else if (g2 == null) {
+                    return 1;
+                }
+                return g2.getType() - g1.getType();
+            }
+        });
+        tc.stop();
+        tc.log("sort data, rows "+rows.size());
+    }
+
+    public boolean hasOperations() {
+        PostProcessFilterOperation filter = this.getFilter();
+        if (filter.hasFilter()) {
+            return true;
+        }
+        if (parameters.getGroupBy() != null) {
+            return true;
+        }
+        return false;
+    }
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/LegendBuilder.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/LegendBuilder.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/LegendBuilder.java	(revision 509)
@@ -0,0 +1,25 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
+
+
+public interface LegendBuilder {
+
+	final public static String DYNMETHOD_BUILDER_NAME = "getLegendBuilder";
+	final public static String DYNMETHOD_GETLEGEND_NAME = "getLegend";
+	final public static String DYNMETHOD_GETLABELING_NAME = "getLabeling";
+
+	public LegendBuilder initialize(FeatureStoreProvider store);
+
+	public void begin();
+
+	public void process(FeatureProvider feature, DGNReader dgnReader);
+
+	public void end();
+
+	public Object getLegend();
+	public Object getLabeling();
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemComplexHeader.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemComplexHeader.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemComplexHeader.java	(revision 509)
@@ -0,0 +1,39 @@
+
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo ComplexHeader.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemComplexHeader extends DGNElemCore {
+	public int totlength; /*!< Total length of surface */
+	public int numelems; /*!< # of elements in surface */
+        
+        public DGNElemComplexHeader(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+        
+        public int getNumElements() {
+            return this.numelems;
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNViewInfo.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNViewInfo.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNViewInfo.java	(revision 509)
@@ -0,0 +1,68 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Informaci�n sobre la vista.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNViewInfo {
+	public int flags;
+	public short[] levels = new short[8]; //8
+	public DGNPoint origin = new DGNPoint();
+	public DGNPoint delta = new DGNPoint();
+	public double[] transmatrx = new double[9]; //9
+	public double conversion;
+	public double activez;
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemText.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemText.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemText.java	(revision 509)
@@ -0,0 +1,94 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo Text.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemText extends DGNElemCore {
+	public int font_id; /*!< Microstation font id, no list available*/
+	public int justification; /*!< Justification, see DGNJ_* */
+	public double length_mult; /*!< Char width in master (if square) */
+	public double height_mult; /*!< Char height in master units */
+	public double height_raw;
+	public double rotation; /*!< Counterclockwise rotation in degrees */
+	public DGNPoint origin = new DGNPoint(); // Bottom left corner of text. 
+	public String string; //Actual text (length varies, \0 terminated
+
+        public DGNElemText(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+
+        public DGNPoint getPoint() {
+            return this.origin;
+        }
+        
+        public double getHeight() {
+            return this.height_mult;
+        }
+        
+        public double getRawHeight() {
+            return this.height_raw;
+        }
+        
+        public double getRotation() {
+            return this.rotation;
+        }
+        
+        public String getText() {
+            return this.string;
+        }
+}
+
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/tagValueUnion.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/tagValueUnion.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/tagValueUnion.java	(revision 509)
@@ -0,0 +1,64 @@
+/*
+ * Created on 21-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Uni�n del valor del tag.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class tagValueUnion {
+	public char[] string;
+	public long integer;
+	public double real;
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNFileHeader.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNFileHeader.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNFileHeader.java	(revision 509)
@@ -0,0 +1,471 @@
+/*
+ * Created on 16-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+import java.nio.MappedByteBuffer;
+
+
+/**
+ * Clase Header del DGN.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNFileHeader {
+	/** DGNElemCore style: Element uses DGNElemCore structure */
+	public static final int DGNST_CORE = 1;
+
+	/** DGNElemCore style: Element uses DGNElemMultiPoint structure */
+	public static final int DGNST_MULTIPOINT = 2;
+
+	/** DGNElemCore style: Element uses DGNElemColorTable structure */
+	public static final int DGNST_COLORTABLE = 3;
+
+	/** DGNElemCore style: Element uses DGNElemTCB structure */
+	public static final int DGNST_TCB = 4;
+
+	/** DGNElemCore style: Element uses DGNElemArc structure */
+	public static final int DGNST_ARC = 5;
+
+	/** DGNElemCore style: Element uses DGNElemText structure */
+	public static final int DGNST_TEXT = 6;
+
+	/** DGNElemCore style: Element uses DGNElemComplexHeader structure */
+	public static final int DGNST_COMPLEX_HEADER = 7;
+
+	/** DGNElemCore style: Element uses DGNElemCellHeader structure */
+	public static final int DGNST_CELL_HEADER = 8;
+
+	/** DGNElemCore style: Element uses DGNElemTagValue structure */
+	public static final int DGNST_TAG_VALUE = 9;
+
+	/** DGNElemCore style: Element uses DGNElemTagSet structure */
+	public static final int DGNST_TAG_SET = 10;
+
+	/** DGNElemCore style: Element uses DGNElemCellLibrary structure */
+	public static final int DGNST_CELL_LIBRARY = 11;
+
+	/** DGNElemCore style: Element uses DGNElemGroup structure */
+	public static final int DGNST_GROUP_DATA = 12;
+	public static final int DGNST_SHARED_CELL_DEFN = 13;
+
+	/* -------------------------------------------------------------------- */
+	/*      Element types                                                   */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNT_NULL = 0;
+	public static final int DGNT_CELL_LIBRARY = 1;
+	public static final int DGNT_CELL_HEADER = 2;
+	public static final int DGNT_LINE = 3;
+	public static final int DGNT_LINE_STRING = 4;
+	public static final int DGNT_GROUP_DATA = 5;
+	public static final int DGNT_SHAPE = 6;
+	public static final int DGNT_TEXT_NODE = 7;
+	public static final int DGNT_DIGITIZER_SETUP = 8;
+	public static final int DGNT_TCB = 9;
+	public static final int DGNT_LEVEL_SYMBOLOGY = 10;
+	public static final int DGNT_CURVE = 11;
+	public static final int DGNT_COMPLEX_CHAIN_HEADER = 12;
+	public static final int DGNT_COMPLEX_SHAPE_HEADER = 14;
+	public static final int DGNT_ELLIPSE = 15;
+	public static final int DGNT_ARC = 16;
+	public static final int DGNT_TEXT = 17;
+	public static final int DGNT_BSPLINE = 21;
+	public static final int DGNT_SHARED_CELL_DEFN = 34;
+	public static final int DGNT_SHARED_CELL_ELEM = 35; // REVISAR
+	public static final int DGNT_TAG_VALUE = 37;
+	public static final int DGNT_APPLICATION_ELEM = 66;
+
+	/* -------------------------------------------------------------------- */
+	/*      Line Styles                                                     */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNS_SOLID = 0;
+	public static final int DGNS_DOTTED = 1;
+	public static final int DGNS_MEDIUM_DASH = 2;
+	public static final int DGNS_LONG_DASH = 3;
+	public static final int DGNS_DOT_DASH = 4;
+	public static final int DGNS_SHORT_DASH = 5;
+	public static final int DGNS_DASH_DOUBLE_DOT = 6;
+	public static final int DGNS_LONG_DASH_SHORT_DASH = 7;
+
+	/* -------------------------------------------------------------------- */
+	/*      Class                                                           */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNC_PRIMARY = 0;
+	public static final int DGNC_PATTERN_COMPONENT = 1;
+	public static final int DGNC_CONSTRUCTION_ELEMENT = 2;
+	public static final int DGNC_DIMENSION_ELEMENT = 3;
+	public static final int DGNC_PRIMARY_RULE_ELEMENT = 4;
+	public static final int DGNC_LINEAR_PATTERNED_ELEMENT = 5;
+	public static final int DGNC_CONSTRUCTION_RULE_ELEMENT = 6;
+
+	/* -------------------------------------------------------------------- */
+	/*      Group Data level numbers.                                       */
+	/*                                                                      */
+	/*      These are symbolic values for the typ 5 (DGNT_GROUP_DATA)       */
+	/*      level values that have special meanings.                        */
+	/* -------------------------------------------------------------------- */
+	public static final int DGN_GDL_COLOR_TABLE = 1;
+	public static final int DGN_GDL_NAMED_VIEW = 3;
+	public static final int DGN_GDL_REF_FILE = 9;
+
+	/* -------------------------------------------------------------------- */
+	/*      Word 17 property flags.                                         */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNPF_HOLE = 0x8000;
+	public static final int DGNPF_SNAPPABLE = 0x4000;
+	public static final int DGNPF_PLANAR = 0x2000;
+	public static final int DGNPF_ORIENTATION = 0x1000;
+	public static final int DGNPF_ATTRIBUTES = 0x0800;
+	public static final int DGNPF_MODIFIED = 0x0400;
+	public static final int DGNPF_NEW = 0x0200;
+	public static final int DGNPF_LOCKED = 0x0100;
+	public static final int DGNPF_CLASS = 0x000f;
+
+	/* -------------------------------------------------------------------- */
+	/*      DGNElementInfo flag values.                                     */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNEIF_DELETED = 0x01;
+	public static final int DGNEIF_COMPLEX = 0x02;
+
+	/* -------------------------------------------------------------------- */
+	/*      Justifications                                                  */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNJ_LEFT_TOP = 0;
+	public static final int DGNJ_LEFT_CENTER = 1;
+	public static final int DGNJ_LEFT_BOTTOM = 2;
+	public static final int DGNJ_LEFTMARGIN_TOP = 3;
+
+	/* text node header only */
+	public static final int DGNJ_LEFTMARGIN_CENTER = 4;
+
+	/* text node header only */
+	public static final int DGNJ_LEFTMARGIN_BOTTOM = 5;
+
+	/* text node header only */
+	public static final int DGNJ_CENTER_TOP = 6;
+	public static final int DGNJ_CENTER_CENTER = 6;
+	public static final int DGNJ_CENTER_BOTTOM = 8;
+	public static final int DGNJ_RIGHTMARGIN_TOP = 9;
+
+	/* text node header only */
+	public static final int DGNJ_RIGHTMARGIN_CENTER = 10;
+
+	/* text node header only */
+	public static final int DGNJ_RIGHTMARGIN_BOTTOM = 11;
+
+	/* text node header only */
+	public static final int DGNJ_RIGHT_TOP = 12;
+	public static final int DGNJ_RIGHT_CENTER = 13;
+	public static final int DGNJ_RIGHT_BOTTOM = 14;
+
+	/* -------------------------------------------------------------------- */
+	/*      DGN file reading options.                                       */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNO_CAPTURE_RAW_DATA = 0x01;
+
+	/* -------------------------------------------------------------------- */
+	/*      Known attribute linkage types, including my synthetic ones.     */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNLT_DMRS = 0x0000;
+	public static final int DGNLT_INFORMIX = 0x3848;
+	public static final int DGNLT_ODBC = 0x5e62;
+	public static final int DGNLT_ORACLE = 0x6091;
+	public static final int DGNLT_RIS = 0x71FB;
+	public static final int DGNLT_SYBASE = 0x4f58;
+	public static final int DGNLT_XBASE = 0x1971;
+	public static final int DGNLT_SHAPE_FILL = 0x0041;
+	public static final int DGNLT_ASSOC_ID = 0x7D2F;
+
+	/* -------------------------------------------------------------------- */
+	/*      File creation options.                                          */
+	/* -------------------------------------------------------------------- */
+	public static final int DGNCF_USE_SEED_UNITS = 0x01;
+	public static final int DGNCF_USE_SEED_ORIGIN = 0x02;
+	public static final int DGNCF_COPY_SEED_FILE_COLOR_TABLE = 0x04;
+	public static final int DGNCF_COPY_WHOLE_SEED_FILE = 0x08;
+	public static final int SIZE_LONG = 4;
+
+        
+        public static final String DGNT_CELL_LIBRARY_NAME = "Cell Library";
+        public static final String DGNT_CELL_HEADER_NAME = "Cell Header";
+        public static final String DGNT_POINT_NAME = "Point";
+        public static final String DGNT_LINE_NAME = "Line";
+        public static final String DGNT_LINE_STRING_NAME = "Line String";
+        public static final String DGNT_GROUP_DATA_NAME = "Group Data";
+        public static final String DGNT_SHAPE_NAME = "Shape";
+        public static final String DGNT_TEXT_NODE_NAME = "Text Node";
+        public static final String DGNT_DIGITIZER_SETUP_NAME = "Digitizer Setup";
+        public static final String DGNT_TCB_NAME = "TCB";
+        public static final String DGNT_LEVEL_SYMBOLOGY_NAME = "Level Symbology";
+        public static final String DGNT_CURVE_NAME = "Curve";
+        public static final String DGNT_COMPLEX_CHAIN_HEADER_NAME = "Complex Chain Header";
+        public static final String DGNT_COMPLEX_SHAPE_HEADER_NAME = "Complex Shape Header";
+        public static final String DGNT_ELLIPSE_NAME = "Ellipse";
+        public static final String DGNT_ARC_NAME = "Arc";
+        public static final String DGNT_TEXT_NAME ="Text";
+        public static final String DGNT_BSPLINE_NAME = "B-Spline";
+        public static final String DGNT_APPLICATION_ELEM_NAME = "Application Element";
+        public static final String DGNT_SHARED_CELL_DEFN_NAME = "Shared Cell Definition";
+        public static final String DGNT_SHARED_CELL_ELEM_NAME = "Shared Cell Element";
+        public static final String DGNT_TAG_VALUE_NAME = "Tag Value";
+        public static final String DGNT_UNKNOWN_NAME = "Unknown";
+        
+	/*
+	   int         offset;
+	   int         size;
+	   int         element_id;
+	   int         stype;
+	   int                level;
+	   int                type;
+	   int                complex;
+	   int                deleted;
+	   int                graphic_group;
+	   int                properties;
+	   int         color;
+	   int         weight;
+	   int         style;
+	   int                attr_bytes;
+	   byte attr_data;
+	   int         raw_bytes;
+	   byte raw_data;
+	   //} DGNElemCore;
+	 */
+
+	/** File Length; */
+	int myFileLength = 0;
+
+	/** Version of the file. */
+	int myVersion = 1000;
+
+	/*
+	   public static final int SHAPE_NULL = 0;
+	    public static final int SHAPE_POINT = 1;
+	    public static final int SHAPE_POLYLINE = 3;
+	    public static final int SHAPE_POLYGON = 5;
+	    public static final int SHAPE_MULTIPOINT = 8;
+	    public static final int SHAPE_POINTZ = 11;
+	    public static final int SHAPE_POLYLINEZ = 13;
+	    public static final int SHAPE_POLYGONZ = 15;
+	    public static final int SHAPE_MULTIPOINTZ = 18;
+	    public static final int SHAPE_POINTM = 21;
+	    public static final int SHAPE_POLYLINEM = 23;
+	    public static final int SHAPE_POLYGONM = 25;
+	    public static final int SHAPE_MULTIPOINTM = 28;
+	    public static final int SHAPE_MULTIPATCH = 31;
+	 */
+	int myDGNType = 0;
+	double myXmin = 0;
+	double myYmin = 0;
+	double myXmax = 0;
+	double myYmax = 0;
+	double myZmin = 0;
+	double myZmax = 0;
+	double myMmin = 0;
+	double myMmax = 0;
+
+	// notify about warnings.
+	private boolean myWarning = true;
+
+	/**
+	 * ShapeFileHeader constructor comment.
+	 */
+	public DGNFileHeader() {
+		super();
+	}
+
+	/**
+	 * Return the version of the file.
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public int getVersion() {
+		return myVersion;
+	}
+
+	/**
+	 * Devuelve el rect�ngulo del fichero.
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public java.awt.geom.Rectangle2D.Double getFileExtents() {
+		return new java.awt.geom.Rectangle2D.Double(myXmin, myYmin,
+			myXmax - myXmin, myYmax - myYmin);
+	}
+
+	/**
+	 * Print warnings to system.out.
+	 *
+	 * @param inWarning DOCUMENT ME!
+	 */
+	public void setWarnings(boolean inWarning) {
+		myWarning = inWarning;
+	}
+
+	/**
+	 * Return the length of the header in 16 bit words..
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public int getHeaderLength() {
+		return 50;
+	}
+
+	/**
+	 * Return the number of 16 bit words in the shape file as recorded in the
+	 * header
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public int getFileLength() {
+		return myFileLength;
+	}
+
+	/**
+	 * Read the header from the shape file.
+	 *
+	 * @param in DOCUMENT ME!
+	 */
+	public void readHeader(MappedByteBuffer in) {
+		//in.order(ByteOrder.BIG_ENDIAN);
+
+		/*
+		   offset=in.getInt();
+		   System.out.println("offset     "+offset);
+		   size=in.getInt();
+		   System.out.println("size        "+size);
+		                   element_id=in.getInt();
+		   System.out.println("element_id          "+element_id);
+		                   stype=in.getInt();
+		   System.out.println("stype        "+stype);
+		                   level=in.getInt();
+		   System.out.println("level          "+level);
+		                   type=in.getInt();
+		   System.out.println("type          "+type);
+		                   complex=in.getInt();
+		   System.out.println("complex          "+complex);
+		                   deleted=in.getInt();
+		   System.out.println("deleted          "+deleted);
+		                   graphic_group=in.getInt();
+		   System.out.println("graphic_group          "+graphic_group);
+		                   properties=in.getInt();
+		   System.out.println("properties          "+properties);
+		                   color=in.getInt();
+		   System.out.println("color          "+color);
+		                   weight=in.getInt();
+		   System.out.println("weight          "+weight);
+		                   style=in.getInt();
+		   System.out.println("style          "+style);
+		                   attr_bytes=in.getInt();
+		   System.out.println("attr_bytes          "+attr_bytes);
+		                   //attr_data=in.get(attr_bytes);
+		   //System.out.println("attr_data          "+attr_data);
+		                   raw_bytes=in.getInt();
+		   System.out.println("raw_bytes          "+raw_bytes);
+		                   //raw_data=in.get(raw_bytes);
+		   //System.out.println("raw_data          "+raw_data);
+		 */
+
+		// the first four bytes are integers
+		// in.setLittleEndianMode(false);
+
+		/*  in.order(ByteOrder.BIG_ENDIAN);
+		   myFileCode = in.getInt();
+		   if (myFileCode != 9994) warn("File Code = "+myFileCode+" Not equal to 9994");
+		   // From 4 to 8 are unused.
+		   myUnused1 = in.getInt();
+		   // From 8 to 12 are unused.
+		   myUnused2 = in.getInt();
+		   // From 12 to 16 are unused.
+		   myUnused3 = in.getInt();
+		   // From 16 to 20 are unused.
+		   myUnused4 = in.getInt();
+		   // From 20 to 24 are unused.
+		   myUnused5 = in.getInt();
+		   // From 24 to 28 are the file length.
+		   myFileLength = in.getInt();
+		   // From 28 to 32 are the File Version.
+		   in.order(ByteOrder.LITTLE_ENDIAN);
+		   myVersion = in.getInt();
+		   // From 32 to 36 are the Shape Type.
+		   myShapeType = in.getInt();
+		   // From 36 to 44 are Xmin.
+		   myXmin = in.getDouble(); // Double.longBitsToDouble(in.getLong());
+		   // From 44 to 52 are Ymin.
+		   myYmin = in.getDouble();
+		   // From 52 to 60 are Xmax.
+		   myXmax = in.getDouble();
+		   // From 60 to 68 are Ymax.
+		   myYmax = in.getDouble();
+		   // From 68 to 76 are Zmin.
+		   myZmin = in.getDouble();
+		   // From 76 to 84 are Zmax.
+		   myZmax = in.getDouble();
+		   // From 84 to 92 are Mmin.
+		   myMmin = in.getDouble();
+		   // From 92 to 100 are Mmax.
+		   myMmax = in.getDouble();
+		   // that is all 100 bytes of the header.
+		 */
+	}
+
+	/**
+	 * Muestra por consola el warning.
+	 *
+	 * @param inWarn DOCUMENT ME!
+	 */
+	private void warn(String inWarn) {
+		if (myWarning) {
+			System.out.print("WARNING: ");
+			System.out.println(inWarn);
+		}
+	}
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNPoint.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNPoint.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNPoint.java	(revision 509)
@@ -0,0 +1,76 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Punto 3D.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNPoint {
+	public double x; /*!< X (normally eastwards) coordinate. */
+	public double y; /*!< y (normally northwards) coordinate. */
+	public double z; /*!< z, up coordinate.  Zero for 2D objects. */
+        
+        public double getX() {
+            return x;
+        }
+
+        public double getY() {
+            return y;
+        }
+        
+        public double getZ() {
+            return z;
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemColorTable.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemColorTable.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemColorTable.java	(revision 509)
@@ -0,0 +1,37 @@
+
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo ColorTable.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemColorTable extends DGNElemCore {
+	public int screen_flag;
+	public byte[][] color_info = new byte[256][3];
+
+	//256 3 /*!< Color table, 256 colors by red (0), green(1) and blue(2) component. */
+
+        public DGNElemColorTable(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNTagDef.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNTagDef.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNTagDef.java	(revision 509)
@@ -0,0 +1,68 @@
+/*
+ * Created on 22-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Definici�n de Tag.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNTagDef {
+	public char[] name; /*!< Name of this tag. */
+	public int id; /*!< Tag index/identifier. */
+	public char[] prompt; /*!< User prompt when requesting value. */
+	public int type;
+
+	/*!< Tag type (one of DGNTT_STRING(1), DGNTT_INTEGER(3) or DGNTT_FLOAT(4). */
+	public tagValueUnion defaultValue; /*!< Default tag value */
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagSet.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagSet.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagSet.java	(revision 509)
@@ -0,0 +1,70 @@
+/*
+ * Created on 22-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo TagSet.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemTagSet extends DGNElemCore {
+	public int tagCount; /*!< Number of tags in tagList. */
+	public int tagSet; /*!< Tag set index. */
+	public int flags; /*!< Tag flags - not too much known. */
+	public char[] tagSetName;
+	public DGNTagDef[] tagList; /*!< List of tag definitions in this set. */
+
+        public DGNElemTagSet(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/double64.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/double64.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/double64.java	(revision 509)
@@ -0,0 +1,63 @@
+/*
+ * Created on 18-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * double de 64.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class double64 {
+	public long hi;
+	public long lo;
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/ByteUtils.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/ByteUtils.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/ByteUtils.java	(revision 509)
@@ -0,0 +1,771 @@
+/*
+ * Created on 21-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+import java.math.BigInteger;
+
+
+/**
+ * Clase que engloba m�todos para trabajar con bytes.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class ByteUtils {
+	public static final int SIZE_BOOL = 1;
+	public static final int SIZE_SHORT = 2;
+	public static final int SIZE_INT = 4;
+	public static final int SIZE_LONG = 8;
+	public static final int SIZE_DOUBLE = 8;
+
+	/** A nibble->char mapping for printing out bytes. */
+	public static final char[] digits = {
+			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
+			'e', 'f'
+		};
+
+	/**
+	 * Return the <code>int</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes read.
+	 *
+	 * @return the value of the <code>int</code> decoded
+	 */
+	public static final int bytesToInt(byte[] data, int[] offset) {
+		/**
+		 * TODO: We use network-order within OceanStore, but temporarily
+		 * supporting intel-order to work with some JNI code until JNI code is
+		 * set to interoperate with network-order.
+		 */
+		int result = 0;
+
+		for (int i = 0; i < SIZE_INT; ++i) {
+			result <<= 8;
+			result |= byteToUnsignedInt(data[offset[0]++]);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Write the bytes representing <code>i</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param i the <code>int</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void intToBytes(int i, byte[] data, int[] offset) {
+		/**
+		 * TODO: We use network-order within OceanStore, but temporarily
+		 * supporting intel-order to work with some JNI code until JNI code is
+		 * set to interoperate with network-order.
+		 */
+		if (data != null) {
+			for (int j = (offset[0] + SIZE_INT) - 1; j >= offset[0]; --j) {
+				data[j] = (byte) i;
+				i >>= 8;
+			}
+		}
+
+		offset[0] += SIZE_INT;
+	}
+
+	/**
+	 * Return the <code>short</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes read.
+	 *
+	 * @return the value of the <code>short</code> decoded
+	 */
+	public static final short bytesToShort(byte[] data, int[] offset) {
+		/**
+		 * TODO: We use network-order within OceanStore, but temporarily
+		 * supporting intel-order to work with some JNI code until JNI code is
+		 * set to interoperate with network-order.
+		 */
+		short result = 0;
+
+		for (int i = 0; i < SIZE_SHORT; ++i) {
+			result <<= 8;
+			result |= (short) byteToUnsignedInt(data[offset[0]++]);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Write the bytes representing <code>s</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param s the <code>short</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void shortToBytes(short s, byte[] data, int[] offset) {
+		/**
+		 * TODO: We use network-order within OceanStore, but temporarily
+		 * supporting intel-order to work with some JNI code until JNI code is
+		 * set to interoperate with network-order.
+		 */
+		if (data != null) {
+			data[offset[0] + 1] = (byte) s;
+			data[offset[0]] = (byte) (s >> 8);
+		}
+
+		offset[0] += SIZE_SHORT;
+	}
+
+	/**
+	 * Return the <code>long</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on  function entry, and which
+	 * 		  on function exit has been incremented by the number of bytes
+	 * 		  read.
+	 *
+	 * @return the value of the <code>long</code> decoded
+	 */
+	public static final long bytesToLong(byte[] data, int[] offset) {
+		long result = 0;
+
+		for (int i = 0; i < SIZE_LONG; ++i) {
+			result <<= 8;
+
+			int res = byteToUnsignedInt(data[offset[0]++]);
+			result = result | res;
+		}
+
+		return result;
+	}
+
+	/**
+	 * Write the bytes representing <code>l</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param l the <code>long</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void longToBytes(long l, byte[] data, int[] offset) {
+		/**
+		 * TODO: We use network-order within OceanStore, but temporarily
+		 * supporting intel-order to work with some JNI code until JNI code is
+		 * set to interoperate with network-order.
+		 */
+		if (data != null) {
+			for (int j = (offset[0] + SIZE_LONG) - 1; j >= offset[0]; --j) {
+				data[j] = (byte) l;
+				l >>= 8;
+			}
+		}
+
+		offset[0] += SIZE_LONG;
+	}
+
+	/**
+	 * Return the <code>double</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on  function entry, and which
+	 * 		  on function exit has been incremented by the number of bytes
+	 * 		  read.
+	 *
+	 * @return the value of the <code>double</code> decoded
+	 */
+	public static final double bytesToDouble(byte[] data, int[] offset) {
+		long bits = bytesToLong(data, offset);
+
+		return Double.longBitsToDouble(bits);
+	}
+
+	/**
+	 * Write the bytes representing <code>d</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param d the <code>double</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void doubleToBytes(double d, byte[] data, int[] offset) {
+		long bits = Double.doubleToLongBits(d);
+		longToBytes(bits, data, offset);
+	}
+
+	/**
+	 * Return the <code>String</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>. This method
+	 * relies on the user using the corresponding <code>stringToBytes</code>
+	 * method to encode the <code>String</code>, so that it may properly
+	 * retrieve the <code>String</code> length.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes read.
+	 *
+	 * @return the value of the <code>String</code> decoded
+	 */
+	public static final String bytesToString(byte[] data, int[] offset) {
+		offset[0] = 0;
+
+		int length = bytesToInt(data, offset);
+		String st = null;
+
+		if ((length < 0) || (length > data.length)) {
+			st = new String(data);
+		} else {
+			st = new String(data, offset[0], length);
+		}
+
+		offset[0] += length;
+
+		return st;
+	}
+
+	/**
+	 * Write the bytes representing <code>s</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param s the <code>String</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void stringToBytes(String s, byte[] data, int[] offset) {
+		byte[] s_bytes = s.getBytes();
+
+		if (data != null) {
+			intToBytes(s_bytes.length, data, offset);
+			memcpy(data, offset[0], s_bytes, 0, s_bytes.length);
+		} else {
+			offset[0] += SIZE_INT;
+		}
+
+		offset[0] += s_bytes.length;
+	}
+
+	/**
+	 * Return the <code>boolean</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on  function entry, and which
+	 * 		  on function exit has been incremented by the number of bytes
+	 * 		  read.
+	 *
+	 * @return the value of the <code>boolean</code> decoded
+	 */
+	public static final boolean bytesToBool(byte[] data, int[] offset) {
+		boolean result = true;
+
+		if (data[offset[0]] == 0) {
+			result = false;
+		}
+
+		offset[0] += SIZE_BOOL;
+
+		return result;
+	}
+
+	/**
+	 * Write the bytes representing <code>b</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param b the <code>boolean</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void boolToBytes(boolean b, byte[] data, int[] offset) {
+		if (data != null) {
+			data[offset[0]] = (byte) (b ? 1 : 0);
+		}
+
+		offset[0] += SIZE_BOOL;
+	}
+
+	/**
+	 * Return the <code>BigInteger</code> represented by the bytes in
+	 * <code>data</code> staring at offset <code>offset[0]</code>.
+	 *
+	 * @param data the array from which to read
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data from which to begin reading on  function entry, and which
+	 * 		  on function exit has been incremented by the number of bytes
+	 * 		  read.
+	 *
+	 * @return the <code>BigInteger</code> decoded
+	 */
+	public static final BigInteger bytesToBigInteger(byte[] data, int[] offset) {
+		int length = bytesToInt(data, offset);
+		byte[] bytes = new byte[length];
+		offset[0] += memcpy(bytes, 0, data, offset[0], length);
+
+		return new BigInteger(bytes);
+	}
+
+	/**
+	 * Write the bytes representing <code>n</code> into the byte array
+	 * <code>data</code>, starting at index <code>offset [0]</code>, and
+	 * increment <code>offset [0]</code> by the number of bytes written; if
+	 * <code>data == null</code>, increment <code>offset [0]</code> by the
+	 * number of bytes that would have been written otherwise.
+	 *
+	 * @param n the <code>BigInteger</code> to encode
+	 * @param data The byte array to store into, or <code>null</code>.
+	 * @param offset A single element array whose first element is the index in
+	 * 		  data to begin writing at on function entry, and which on
+	 * 		  function exit has been incremented by the number of bytes
+	 * 		  written.
+	 */
+	public static final void bigIntegerToBytes(BigInteger n, byte[] data,
+		int[] offset) {
+		byte[] bytes = n.toByteArray();
+		intToBytes(bytes.length, data, offset);
+		offset[0] += memcpy(data, offset[0], bytes, 0, bytes.length);
+	}
+
+	/**
+	 * Convert an array of <code>bytes</code>s into an array of
+	 * <code>ints</code>.
+	 *
+	 * @param dst the array to write
+	 * @param dst_offset the start offset in <code>dst</code>, times 4. This
+	 * 		  measures the offset as if <code>dst</code> were an array of
+	 * 		  <code>byte</code>s (rather than <code>int</code>s).
+	 * @param src the array to read
+	 * @param src_offset the start offset in <code>src</code>
+	 * @param length the number of <code>byte</code>s to copy.
+	 */
+	public static final void bytesToInts(int[] dst, int dst_offset, byte[] src,
+		int src_offset, int length) {
+		if ((src == null) || (dst == null) ||
+				((src_offset + length) > src.length) ||
+				((dst_offset + length) > (dst.length * 4)) ||
+				((dst_offset % 4) != 0) || ((length % 4) != 0)) {
+			croak("bytesToInts parameters are invalid" + " src==" + src +
+				" dst==" + dst +
+				(((src == null) || (dst == null)) ? " "
+												  : (" (src_offset+length)>src.length==" +
+				(src_offset + length) + ">" + src.length +
+				" (dst_offset+length)>(dst.length*4)==" +
+				(dst_offset + length) + ">" + (dst.length * 4) +
+				" (dst_offset%4)==" + (dst_offset % 4) + " (length%4)==" +
+				(length % 4) + " dest.length==" + dst.length + " length==" +
+				length)));
+		}
+
+		// Convert parameters to normal format
+		int[] offset = new int[1];
+		offset[0] = src_offset;
+
+		int int_dst_offset = dst_offset / 4;
+
+		for (int i = 0; i < (length / 4); ++i) {
+			dst[int_dst_offset++] = bytesToInt(src, offset);
+		}
+	}
+
+	/**
+	 * Convert an array of <code>int</code>s into an array of
+	 * <code>bytes</code>.
+	 *
+	 * @param dst the array to write
+	 * @param dst_offset the start offset in <code>dst</code>
+	 * @param src the array to read
+	 * @param src_offset the start offset in <code>src</code>, times 4. This
+	 * 		  measures the offset as if <code>src</code> were an array of
+	 * 		  <code>byte</code>s (rather than <code>int</code>s).
+	 * @param length the number of <code>byte</code>s to copy.
+	 */
+	public static final void intsToBytes(byte[] dst, int dst_offset, int[] src,
+		int src_offset, int length) {
+		if ((src == null) || (dst == null) ||
+				((dst_offset + length) > dst.length) ||
+				((src_offset + length) > (src.length * 4)) ||
+				((src_offset % 4) != 0) || ((length % 4) != 0)) {
+			croak("intsToBytes parameters are invalid:" + " src=" + src +
+				" dst=" + dst + " (dst_offset=" + dst_offset + " + length=" +
+				length + ")=" + (dst_offset + length) + " > dst.length=" +
+				((dst == null) ? 0 : dst.length) + " (src_offset=" +
+				src_offset + " + length=" + length + ")=" +
+				(src_offset + length) + " > (src.length=" +
+				((src == null) ? 0 : src.length) + "*4)=" +
+				((src == null) ? 0 : (src.length * 4)) + " (src_offset=" +
+				src_offset + " % 4)=" + (src_offset % 4) + " != 0" +
+				" (length=" + length + " % 4)=" + (length % 4) + " != 0");
+		}
+
+		// Convert parameters to normal format
+		int[] offset = new int[1];
+		offset[0] = dst_offset;
+
+		int int_src_offset = src_offset / 4;
+
+		for (int i = 0; i < (length / 4); ++i) {
+			intToBytes(src[int_src_offset++], dst, offset);
+		}
+	}
+
+	/**
+	 * Convert a <code>byte</code> into an unsigned integer.
+	 *
+	 * @param b the <code>byte</code> to cast
+	 *
+	 * @return a postiive <code>int</code> whose lowest byte contains the bits
+	 * 		   of <code>b</code>.
+	 */
+	public static final int byteToUnsignedInt(byte b) {
+		return (b) & 0xff;
+	}
+
+	/**
+	 * Copy contents of one array of <code>bytes</code> into another. If either
+	 * array is <code>null</code>, simply return the <code>length</code>
+	 * parameter directly.
+	 *
+	 * @param dst the array to write, or <code>null</code>
+	 * @param dst_offset the start offset in <code>dst</code>
+	 * @param src the array to read, or <code>null</code>
+	 * @param src_offset the start offset in <code>src</code>
+	 * @param length the number of <code>byte</code>s to copy.
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static int memcpy(byte[] dst, int dst_offset, byte[] src,
+		int src_offset, int length) {
+		if ((dst != null) && (src != null)) {
+			if (dst.length < (dst_offset + length)) {
+				croak("dst.length = " + dst.length + ", but " +
+					"dst_offset = " + dst_offset + " and length = " + length +
+					".");
+			}
+
+			if (src.length < (src_offset + length)) {
+				croak("src.length = " + src.length + ", but " +
+					"src_offset = " + src_offset + " and length = " + length +
+					".");
+			}
+
+			for (int i = 0; i < length; ++i, ++dst_offset, ++src_offset) {
+				dst[dst_offset] = src[src_offset];
+			}
+		}
+
+		return length;
+	}
+
+	/**
+	 * Compare the contents of one array of <code>bytes</code> to another.
+	 *
+	 * @param a the first array
+	 * @param a_offset the start offset in <code>a</code>
+	 * @param b the second array
+	 * @param b_offset the start offset in <code>b</code>
+	 * @param length the number of <code>byte</code>s to compare.
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static boolean memcmp(byte[] a, int a_offset, byte[] b,
+		int b_offset, int length) {
+		if ((a == null) && (b == null)) {
+			return true;
+		}
+
+		if ((a == null) || (b == null)) {
+			return false;
+		}
+
+		for (int i = 0; i < length; ++i, ++a_offset, ++b_offset) {
+			if (a[a_offset] != b[b_offset]) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Fill the given array with zeros.
+	 *
+	 * @param array the array to clear
+	 * @param offset the start offset
+	 * @param length the number of <code>byte</code>s to clear.
+	 */
+	public static void memclr(byte[] array, int offset, int length) {
+		for (int i = 0; i < length; ++i, ++offset) {
+			array[offset] = 0;
+		}
+	}
+
+	/**
+	 * Round a number up to a given multiple.
+	 *
+	 * @param value the number to be rounded
+	 * @param multiple the number to which to be rounded
+	 *
+	 * @return the smallest <code>int</code> greater than or equal to
+	 * 		   <code>value</code> which divides <code>multiple</code> exactly.
+	 */
+	public static int round_up(int value, int multiple) {
+		return (((value - 1) / multiple) + 1) * multiple;
+	}
+
+	/**
+	 * Return a new array equal to original except zero-padded to an integral
+	 * mulitple of blocks.  If the original is already an integral multiple of
+	 * blocks, just return it.
+	 *
+	 * @param original the array of <code>byte</code>s to be padded
+	 * @param block_size the size of the blocks
+	 *
+	 * @return an array whose size divides <code>block_size</code> exactly. The
+	 * 		   array is either <code>original</code> itself, or a copy whose
+	 * 		   first <code>original.length</code> bytes are equal to
+	 * 		   <code>original</code>.
+	 */
+	public static byte[] zero_pad(byte[] original, int block_size) {
+		if ((original.length % block_size) == 0) {
+			return original;
+		}
+
+		byte[] result = new byte[round_up(original.length, block_size)];
+		memcpy(result, 0, original, 0, original.length);
+
+		// Unnecessary - jvm sets bytes to 0.
+		// memclr (result, original.length, result.length - original.length);
+		return result;
+	}
+
+	/**
+	 * Determines whether two arrays of <code>byte</code>s contain the same
+	 * contents.
+	 *
+	 * @param b1 The first array
+	 * @param b2 The second array
+	 *
+	 * @return <code>true</code> if both arrays are <code>null</code>, both
+	 * 		   empty, or both of the same length with equal contents.
+	 */
+	public static boolean equals(byte[] b1, byte[] b2) {
+		if (b1 == b2) {
+			return true;
+		}
+
+		if ((b1 == null) || (b2 == null)) { // only one is null
+
+			return false;
+		}
+
+		if (b1.length != b2.length) {
+			return false;
+		}
+
+		for (int i = 0; i < b1.length; ++i) {
+			if (b1[i] != b2[i]) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Produce a <code>String</code> representation for the specified array of
+	 * <code>byte</code>s.  Print each <code>byte</code> as two hexadecimal
+	 * digits.
+	 *
+	 * @param data The array to print
+	 * @param offset the start offset in <code>data</code>
+	 * @param length the number of <code>byte</code>s to print
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static String print_bytes(byte[] data, int offset, int length) {
+		int size = 2 * length;
+		size += ((size / 8) + (size / 64));
+
+		char[] buf = new char[size];
+		int low_mask = 0x0f;
+		int high_mask = 0xf0;
+		int buf_pos = 0;
+		byte b;
+
+		int j = 0;
+
+		for (int i = offset; i < (offset + length); ++i) {
+			b = data[i];
+			buf[buf_pos++] = digits[(high_mask & b) >> 4];
+			buf[buf_pos++] = digits[(low_mask & b)];
+
+			if ((j % 4) == 3) {
+				buf[buf_pos++] = ' ';
+			}
+
+			if ((j % 32) == 31) {
+				buf[buf_pos++] = '\n';
+			}
+
+			++j;
+		}
+
+		return new String(buf);
+	}
+
+	/**
+	 * DOCUMENT ME!
+	 *
+	 * @param data DOCUMENT ME!
+	 * @param offset DOCUMENT ME!
+	 * @param length DOCUMENT ME!
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static String print_bytes_exact(byte[] data, int offset, int length) {
+		int size = 2 * length;
+		char[] buf = new char[size];
+		int low_mask = 0x0f;
+		int high_mask = 0xf0;
+		int buf_pos = 0;
+		byte b;
+
+		int j = 0;
+
+		for (int i = offset; i < (offset + length); ++i) {
+			b = data[i];
+			buf[buf_pos++] = digits[(high_mask & b) >> 4];
+			buf[buf_pos++] = digits[(low_mask & b)];
+			++j;
+		}
+
+		return new String(buf);
+	}
+
+	/**
+	 * DOCUMENT ME!
+	 *
+	 * @param data DOCUMENT ME!
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static String print_bytes(byte[] data) {
+		return print_bytes(data, 0, data.length);
+	}
+
+	/**
+	 * DOCUMENT ME!
+	 *
+	 * @param msg DOCUMENT ME!
+	 */
+	private static void croak(String msg) {
+		// throw new java.AssertionViolatedException(msg);
+	}
+
+	/**
+	 * DOCUMENT ME!
+	 *
+	 * @param b DOCUMENT ME!
+	 *
+	 * @return DOCUMENT ME!
+	 */
+	public static int getUnsigned(byte b) {
+		return ((b & 0xff)); // >> 8);
+	}
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellHeader.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellHeader.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellHeader.java	(revision 509)
@@ -0,0 +1,46 @@
+
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo CellHeader.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemCellHeader extends DGNElemCore {
+	public int totlength; /*!< Total length of cell */
+	public byte[] name = new byte[7]; //7           /*!< Cell name */
+	public int cclass; /*!< Class bitmap */
+	public int[] levels = new int[4]; //4         /*!< Levels used in cell */
+	public DGNPoint rnglow = new DGNPoint(); /*!< X/Y/Z minimums for cell */
+	public DGNPoint rnghigh = new DGNPoint(); /*!< X/Y/Z minimums for cell */
+	public double[] trans = new double[9];
+
+	//9          /*!< 2D/3D Transformation Matrix */
+	public DGNPoint origin = new DGNPoint(); /*!< Cell Origin */
+	public double xscale;
+	public double yscale;
+	public double rotation;
+        
+        public DGNElemCellHeader(DGNReader dgnreader) {
+            super(dgnreader);
+        }          
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCore.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCore.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCore.java	(revision 509)
@@ -0,0 +1,159 @@
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+import java.util.Formatter;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo Base del cual extienden los
+ * dem�s tipos.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemCore {
+	public int offset;
+	public int size;
+	public int element_id; /*!< Element number (zero based) */
+	public int stype; /*!< Structure type: (DGNST_*) */
+	public int level; /*!< Element Level: 0-63 */
+	public int type; /*!< Element type (DGNT_) */
+	public int complex; /*!< Is element complex? */
+	public int deleted; /*!< Is element deleted? */
+	public int graphic_group; /*!< Graphic group number */
+	public int properties; /*!< Properties: ORing of DGNPF_ flags */
+	public int color; /*!< Color index (0-255) */
+	public int weight; /*!< Line Weight (0-31) */
+	public int style; /*!< Line Style: One of DGNS_* values */
+	public int attr_bytes; /*!< Bytes of attribute data, usually zero. */
+	public byte[] attr_data; /*!< Raw attribute data */
+	public int raw_bytes; /*!< Bytes of raw data, usually zero. */
+	public byte[] raw_data; /*!< All raw element data including header. */
+        
+        protected DGNReader dgnreader = null;
+        
+        public DGNElemCore(DGNReader dgnreader) {
+            this.dgnreader = dgnreader;
+        }
+        
+        public boolean isComplex() {
+            return this.complex != 0;
+        }
+        
+        public boolean isDeleted() {
+            return this.deleted != 0;
+        }
+        
+        public boolean isHole() {
+            if( this.type != DGNFileHeader.DGNT_SHAPE ) {
+                return false;
+            }
+            return (this.properties & DGNFileHeader.DGNPF_HOLE) != 0;
+        }
+        
+        public boolean is3D() {
+            return this.getDimensions()==3;
+        }
+        
+        public boolean isComplexShapeHeader() {
+            return type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER;
+        }
+        
+        public boolean isShape() {
+            return this.type == DGNFileHeader.DGNT_SHAPE;
+        }
+        
+        public boolean isEllipse() {
+            return type == DGNFileHeader.DGNT_ELLIPSE;
+        }
+        
+        public boolean isCurve() {
+            return type == DGNFileHeader.DGNT_CURVE;
+        }
+        
+        public int getShapeFillColor() {
+            return this.dgnreader.DGNGetShapeFillInfo(this);
+        }
+        
+        public String getLevelAsString() {
+            return String.valueOf(this.level);
+        }
+        
+        public int getLevel() {
+            return this.level;
+        }
+        
+        public int getStyle() {
+            return this.style;
+        }
+
+        public int getWeight() {
+            return this.weight;
+        }
+        
+        public String getEntityName() {
+            return this.dgnreader.DGNTypeToName(this.type);
+        }
+        
+        public int getColor() {
+            return this.color;
+        }
+        
+        public int getID() {
+            return this.element_id;
+        }
+        
+        public int getGroup() {
+            return this.graphic_group;
+        }
+        
+        public double getElevation() {
+            return 0;
+        }
+
+        public int getDimensions() {
+            return this.dgnreader.getInfo().dimension;
+        }
+
+        public int getType() {
+            return this.type;
+        }
+
+        public int getSType() {
+            return this.stype;
+        }
+        
+
+        public byte[] getData() {
+            return this.raw_data;
+        }
+
+        public String getDataAsHexadecimal() {
+            if( this.raw_data == null ) {
+                return null;
+            }
+            Formatter out = new Formatter();
+
+            for (int i = 0; i < this.raw_data.length; i++) {
+                int ch = this.raw_data[i] & 0xff;
+                out.format("%02X", ch);
+            }
+            return out.toString();
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNInfo.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNInfo.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNInfo.java	(revision 509)
@@ -0,0 +1,100 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase que almacena informaci�n del elemento.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNInfo {
+	public String fp;
+	public int ftall;
+	public int next_element_id;
+	public int nElemBytes;
+	public byte[] abyElem = new byte[131076]; //131076
+
+	//byte[] temporal=new byte[4];
+	public int got_tcb;
+	public int dimension;
+	public int options;
+	public double scale;
+	public double origin_x;
+	public double origin_y;
+	public double origin_z;
+	public int index_built;
+	public int element_count;
+	public int max_element_count;
+	public DGNElementInfo[] element_index;
+	public int got_color_table;
+	public byte[][] color_table = new byte[256][3]; //256 3
+	public int got_bounds;
+	public double min_x;
+	public double min_y;
+	public double min_z;
+	public double max_x;
+	public double max_y;
+	public double max_z;
+	public int has_spatial_filter;
+	public int sf_converted_to_uor;
+	public int select_complex_group;
+	public int in_complex_group;
+	public long sf_min_x;
+	public long sf_min_y;
+	public long sf_max_x;
+	public long sf_max_y;
+	public double sf_min_x_geo;
+	public double sf_min_y_geo;
+	public double sf_max_x_geo;
+	public double sf_max_y_geo;
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNLink.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNLink.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNLink.java	(revision 509)
@@ -0,0 +1,51 @@
+
+
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+import java.util.Formatter;
+
+
+public class DGNLink {
+    int index;
+    int type;
+    int entityNum;
+    int msLink;
+    int length;
+    byte[] data;
+
+    public int getIndex() {
+        return this.index;
+    }
+    
+    public int getType() {
+        return this.type;
+    }
+
+    public int getEntityCode() {
+        return this.entityNum;
+    }
+
+    public int getMSLink() {
+        return this.msLink;
+    }
+
+    public int getLength() {
+        return this.length;
+    }
+
+    public byte[] getData() {
+        return this.data;
+    }
+    
+    public String getDataAsHexadecimal() {
+        Formatter out = new Formatter();
+
+        for (int i = 0; i < this.data.length; i++) {
+            int ch = this.data[i] & 0xff;
+            out.format("%02X", ch);
+        }
+        return out.toString();
+    }
+    
+   
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemGroup.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemGroup.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemGroup.java	(revision 509)
@@ -0,0 +1,78 @@
+/*
+ * Created on 07-jul-2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo Group.
+ *
+ * @author FJP
+ */
+public class DGNElemGroup extends DGNElemCore {
+	/*                 typedef struct
+	   {
+	   Elm_hdr ehdr; // element header
+	   Disp_hdr dhdr; // display header
+	   short file_chars; // no. of chars. in file spec
+	   char file_spec[65] //file specification
+	   byte file_num; // file number
+	   Fb_opts fb_opts; // file builder options mask
+	   Fd_opts fd_opts; // file displayer options mask
+	   byte disp_flags[16]; // display flags
+	   short lev_flags[8][4]; // level on/off flags
+	   long ref_org[3]; // origin in ref file uors
+	   double trns_mtrx[9]; // transformation matrix
+	   double cnvrs_fact; // conversion factor
+	   Group Data Elements (Type 5)
+	   long mast_org[3]; // origin in master file uors
+	   short log_chars; // characters in logical name
+	   char log_name[22]; // logical name (padded)
+	   short desc_chars; // characters in description
+	   char description[42]; /* description (padded)
+	   short lev_sym_mask; // level symbology enable mask
+	   short lev_sym[63]; // level symbology descriptor
+	   long z_delta; // Z-direction delta
+	   short clip_vertices; // clipping vertices
+	   Point2d clip_poly[1]; // clipping polygon
+	   } Ref_file_type5; */
+
+	public DGNPoint origin = new DGNPoint(); /*!< Origin of ellipse */
+	public double primary_axis;
+
+	//=new double[4];	/*!< Primary axis length */
+	public double secondary_axis;
+
+	//=new double[4]; /*!< Secondary axis length */
+	public double rotation; /*!< Counterclockwise rotation in degrees */
+	public double[] quat = new double[4]; //4
+	public double startang;
+
+	/*!< Start angle (degrees counterclockwise of primary axis) */
+	public double sweepang; /*!< Sweep angle (degrees) */
+        
+        public DGNElemGroup(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNReader.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNReader.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNReader.java	(revision 509)
@@ -0,0 +1,3291 @@
+/**
+ * gvSIG. Desktop Geographic Information System.
+ *
+ * Copyright (C) 2007-2013 gvSIG Association.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * For any additional information, do not hesitate to contact us at info AT
+ * gvsig.com, or visit our website www.gvsig.com.
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.gvsig.fmap.dal.exception.DataException;
+import org.gvsig.fmap.dal.exception.ReadException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Clase dedicada a leer del fichero DGN.
+ *
+ */
+public class DGNReader {
+
+    private static Logger logger = LoggerFactory.getLogger(DGNReader.class);
+    static int[][] abyDefaultPCT = {{255, 255, 255}, {0, 0, 255},
+    {0, 255, 0}, {255, 0, 0}, {255, 255, 0}, {255, 0, 255},
+    {255, 127, 0}, {0, 255, 255}, {64, 64, 64},
+    {192, 192, 192}, {254, 0, 96}, {160, 224, 0},
+    {0, 254, 160}, {128, 0, 160}, {176, 176, 176},
+    {0, 240, 240}, {240, 240, 240}, {0, 0, 240}, {0, 240, 0},
+    {240, 0, 0}, {240, 240, 0}, {240, 0, 240}, {240, 122, 0},
+    {0, 240, 240}, {240, 240, 240}, {0, 0, 240}, {0, 240, 0},
+    {240, 0, 0}, {240, 240, 0}, {240, 0, 240}, {240, 122, 0},
+    {0, 225, 225}, {225, 225, 225}, {0, 0, 225}, {0, 225, 0},
+    {225, 0, 0}, {225, 225, 0}, {225, 0, 225}, {225, 117, 0},
+    {0, 225, 225}, {225, 225, 225}, {0, 0, 225}, {0, 225, 0},
+    {225, 0, 0}, {225, 225, 0}, {225, 0, 225}, {225, 117, 0},
+    {0, 210, 210}, {210, 210, 210}, {0, 0, 210}, {0, 210, 0},
+    {210, 0, 0}, {210, 210, 0}, {210, 0, 210}, {210, 112, 0},
+    {0, 210, 210}, {210, 210, 210}, {0, 0, 210}, {0, 210, 0},
+    {210, 0, 0}, {210, 210, 0}, {210, 0, 210}, {210, 112, 0},
+    {0, 195, 195}, {195, 195, 195}, {0, 0, 195}, {0, 195, 0},
+    {195, 0, 0}, {195, 195, 0}, {195, 0, 195}, {195, 107, 0},
+    {0, 195, 195}, {195, 195, 195}, {0, 0, 195}, {0, 195, 0},
+    {195, 0, 0}, {195, 195, 0}, {195, 0, 195}, {195, 107, 0},
+    {0, 180, 180}, {180, 180, 180}, {0, 0, 180}, {0, 180, 0},
+    {180, 0, 0}, {180, 180, 0}, {180, 0, 180}, {180, 102, 0},
+    {0, 180, 180}, {180, 180, 180}, {0, 0, 180}, {0, 180, 0},
+    {180, 0, 0}, {180, 180, 0}, {180, 0, 180}, {180, 102, 0},
+    {0, 165, 165}, {165, 165, 165}, {0, 0, 165}, {0, 165, 0},
+    {165, 0, 0}, {165, 165, 0}, {165, 0, 165}, {165, 97, 0},
+    {0, 165, 165}, {165, 165, 165}, {0, 0, 165}, {0, 165, 0},
+    {165, 0, 0}, {165, 165, 0}, {165, 0, 165}, {165, 97, 0},
+    {0, 150, 150}, {150, 150, 150}, {0, 0, 150}, {0, 150, 0},
+    {150, 0, 0}, {150, 150, 0}, {150, 0, 150}, {150, 92, 0},
+    {0, 150, 150}, {150, 150, 150}, {0, 0, 150}, {0, 150, 0},
+    {150, 0, 0}, {150, 150, 0}, {150, 0, 150}, {150, 92, 0},
+    {0, 135, 135}, {135, 135, 135}, {0, 0, 135}, {0, 135, 0},
+    {135, 0, 0}, {135, 135, 0}, {135, 0, 135}, {135, 87, 0},
+    {0, 135, 135}, {135, 135, 135}, {0, 0, 135}, {0, 135, 0},
+    {135, 0, 0}, {135, 135, 0}, {135, 0, 135}, {135, 87, 0},
+    {0, 120, 120}, {120, 120, 120}, {0, 0, 120}, {0, 120, 0},
+    {120, 0, 0}, {120, 120, 0}, {120, 0, 120}, {120, 82, 0},
+    {0, 120, 120}, {120, 120, 120}, {0, 0, 120}, {0, 120, 0},
+    {120, 0, 0}, {120, 120, 0}, {120, 0, 120}, {120, 82, 0},
+    {0, 105, 105}, {105, 105, 105}, {0, 0, 105}, {0, 105, 0},
+    {105, 0, 0}, {105, 105, 0}, {105, 0, 105}, {105, 77, 0},
+    {0, 105, 105}, {105, 105, 105}, {0, 0, 105}, {0, 105, 0},
+    {105, 0, 0}, {105, 105, 0}, {105, 0, 105}, {105, 77, 0},
+    {0, 90, 90}, {90, 90, 90}, {0, 0, 90}, {0, 90, 0},
+    {90, 0, 0}, {90, 90, 0}, {90, 0, 90}, {90, 72, 0},
+    {0, 90, 90}, {90, 90, 90}, {0, 0, 90}, {0, 90, 0},
+    {90, 0, 0}, {90, 90, 0}, {90, 0, 90}, {90, 72, 0},
+    {0, 75, 75}, {75, 75, 75}, {0, 0, 75}, {0, 75, 0},
+    {75, 0, 0}, {75, 75, 0}, {75, 0, 75}, {75, 67, 0},
+    {0, 75, 75}, {75, 75, 75}, {0, 0, 75}, {0, 75, 0},
+    {75, 0, 0}, {75, 75, 0}, {75, 0, 75}, {75, 67, 0},
+    {0, 60, 60}, {60, 60, 60}, {0, 0, 60}, {0, 60, 0},
+    {60, 0, 0}, {60, 60, 0}, {60, 0, 60}, {60, 62, 0},
+    {0, 60, 60}, {60, 60, 60}, {0, 0, 60}, {0, 60, 0},
+    {60, 0, 0}, {60, 60, 0}, {60, 0, 60}, {60, 62, 0},
+    {0, 45, 45}, {45, 45, 45}, {0, 0, 45}, {0, 45, 0},
+    {45, 0, 0}, {45, 45, 0}, {45, 0, 45}, {45, 57, 0},
+    {0, 45, 45}, {45, 45, 45}, {0, 0, 45}, {0, 45, 0},
+    {45, 0, 0}, {45, 45, 0}, {45, 0, 45}, {45, 57, 0},
+    {0, 30, 30}, {30, 30, 30}, {0, 0, 30}, {0, 30, 0},
+    {30, 0, 0}, {30, 30, 0}, {30, 0, 30}, {30, 52, 0},
+    {0, 30, 30}, {30, 30, 30}, {0, 0, 30}, {0, 30, 0},
+    {30, 0, 0}, {30, 30, 0}, {30, 0, 30}, {192, 192, 192},
+    {28, 0, 100}};
+    private int LSB;
+    private FileInputStream fin;
+
+    // private LEDataInputStream input;
+    private MappedByteBuffer bb;
+    private int FALSE = 0;
+    private int TRUE = 1;
+    private DGNElemCore elemento;
+    private DGNInfo info; // Contiene el path y otras cosas
+    private Rectangle2D.Double m_BoundingBox;
+    private DGNElemColorTable m_colorTable;
+
+    private boolean logErrors = false;
+
+    public DGNReader(String pathFich) throws DataException {
+        this(pathFich, false);
+    }
+
+    public DGNReader(String pathFich, boolean logErrors) throws DataException {
+        this.logErrors = logErrors;
+
+        info = new DGNInfo();
+
+        DGNElemCore elemento = new DGNElemCore(this);
+        int iArg;
+        int bReportExtents = 0;
+        byte[] achRaw = new byte[64];
+        achRaw[63] = 1;
+
+        double dfSFXMin = 0.0;
+        double dfSFXMax = 0.0;
+        double dfSFYMin = 0.0;
+        double dfSFYMax = 0.0;
+
+        info.fp = pathFich;
+        info = DGNOpen(info, 0);
+
+        bb.rewind();
+        DGNSetSpatialFilter(info, dfSFXMin, dfSFYMin, dfSFXMax, dfSFYMax);
+
+        int nLevel;
+        int nType;
+        int[] anLevelTypeCount = new int[128 * 64];
+        int[] anLevelCount = new int[64];
+        int[] anTypeCount = new int[128];
+        double[] adfExtents = new double[6];
+        int[] nCount = new int[1];
+        nCount[0] = 0;
+
+        DGNGetExtents(info, adfExtents); // extender
+        logdebug("X Range:" + adfExtents[0] + ", " + adfExtents[3]);
+        logdebug("Y Range:" + adfExtents[1] + ", " + adfExtents[4]);
+        logdebug("Z Range:" + adfExtents[2] + ", " + adfExtents[5]);
+
+        m_BoundingBox = new Rectangle2D.Double();
+        m_BoundingBox.setRect(adfExtents[0], adfExtents[1],
+                (adfExtents[3] - adfExtents[0]),
+                (adfExtents[4] - adfExtents[1]));
+
+        /* m_Renderer = new FRenderer(this); */
+        DGNElementInfo[] pasEI; // =new DGNElementInfo[nCount+1];
+        pasEI = DGNGetElementIndex(info, nCount);
+
+        logdebug("Total Elements:" + nCount[0]);
+
+        for (int i = 0; i < nCount[0]; i++) {
+            anLevelTypeCount[(pasEI[i].level * 128) + pasEI[i].type]++;
+            anLevelCount[pasEI[i].level]++;
+            anTypeCount[pasEI[i].type]++;
+        }
+
+        logdebug("Per Type Report");
+        logdebug("===============");
+
+        for (nType = 0; nType < 128; nType++) {
+            if (anTypeCount[nType] != 0) {
+                logdebug("Type:" + DGNTypeToName(nType) + ":"
+                        + anTypeCount[nType]);
+            }
+        }
+
+        logdebug("Per Level Report\n");
+        logdebug("================\n");
+        for (nLevel = 0; nLevel < 64; nLevel++) {
+            if (anLevelCount[nLevel] == 0) {
+                continue;
+            }
+            logdebug("Level " + nLevel + "," + anLevelCount[nLevel] + "elements:");
+            for (nType = 0; nType < 128; nType++) {
+                if (anLevelTypeCount[(nLevel * 128) + nType] != 0) {
+                    logdebug("  Type " + DGNTypeToName(nType)
+                            + "," + anLevelTypeCount[(nLevel * 128) + nType]);
+                }
+            }
+        }
+
+        bb.rewind();
+    }
+
+    public boolean is3D() {
+        return this.info.dimension == 3;
+    }
+
+    /*
+     * public Color getColor(int indexColor) { int r,g,b; //
+     * System.err.println("indexcolor = " + indexColor); // Si no hay tabla de
+     * colores, interpretamos que todas las cosas son negras if (m_colorTable ==
+     * null) return new Color(0,0,0);
+     * 
+     * r = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][0]); g =
+     * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][1]); b =
+     * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][2]);
+     * 
+     * if ((r==255) && (g==255) & (b==255)) { r=g=b=0; // El color blanco lo
+     * devolvemos como negro. }
+     * 
+     * return new Color(r,g,b); }
+     */
+    /**
+     * Devuelve la informaci�n del DGN.
+     *
+     * @return DGNInfo Informaci�n.
+     */
+    public DGNInfo getInfo() {
+        return info;
+    }
+
+    /**
+     * Devuelve el n�mero de elementos.
+     *
+     * @return N�mero de elementos.
+     */
+    public int getNumEntities() {
+        return info.element_count;
+    }
+
+    /**
+     * Devuelve el rect�ngulo del extent.
+     *
+     * @return Rect�ngulo.
+     */
+    public Rectangle2D getBoundingBox() {
+        return m_BoundingBox;
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGNGotoElement() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Seek to indicated element. Changes what element will be read on the next
+     * call to DGNReadElement(). Note that this function requires and index, and
+     * one will be built if not already available.
+     *
+     * @param element_id the element to seek to. These values are sequentially
+     * ordered starting at zero for the first element.
+     *
+     * @return returns TRUE on success or FALSE on failure.
+     */
+    public int DGNGotoElement(int element_id) {
+        DGNBuildIndex(info);
+        if ((element_id < 0) || (element_id >= info.element_count)) {
+            return FALSE;
+        }
+        bb.position((int) info.element_index[element_id].offset);
+
+        info.next_element_id = element_id;
+        info.in_complex_group = FALSE;
+        return TRUE;
+    }
+
+    private DGNInfo DGNOpen(DGNInfo info, int bUpdate) throws DataException {
+        int pos = 0;
+        byte[] abyHeader = new byte[512];
+        info.next_element_id = 0;
+        info.got_tcb = FALSE;
+        info.scale = 1.0;
+        info.origin_x = 0.0;
+        info.origin_y = 0.0;
+        info.origin_z = 0.0;
+        info.index_built = FALSE;
+        info.element_count = 0;
+        info.element_index = null;
+        info.got_bounds = FALSE;
+
+        try {
+            fin = new FileInputStream(info.fp);
+
+            FileChannel fc = fin.getChannel();
+
+            long sz = fc.size();
+            int numReg;
+
+            // Get the file's size and then map it into memory
+            bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
+            bb.order(ByteOrder.nativeOrder());
+            bb.get(abyHeader, pos, abyHeader.length);
+
+            info.ftall = (int) (sz / 16);
+
+            if (bb.order() == ByteOrder.LITTLE_ENDIAN) {
+                LSB = TRUE;
+            }
+
+            if (DGNTestOpen(abyHeader, abyHeader.length) != FALSE) {
+                if (abyHeader[0] == (byte) 0xC8) {
+                    info.dimension = 3; // 0xC8
+                } else {
+                    info.dimension = 2;
+                }
+
+                info.has_spatial_filter = FALSE;
+                info.sf_converted_to_uor = FALSE;
+                info.select_complex_group = FALSE;
+                info.in_complex_group = FALSE;
+            }
+        } catch (FileNotFoundException e) {
+            throw new org.gvsig.fmap.dal.exception.FileNotFoundException(
+                    info.fp);
+        } catch (Exception e) {
+            throw new ReadException("DGNReader error", e);
+        }
+
+        return info;
+    }
+
+    /**
+     * Comprobaci�n si se puede abrir el fichero.
+     *
+     * @param pabyHeader Vector byte con el header.
+     * @param nByteCount n�mero de bytes.
+     *
+     * @return Devuelve un enteor que muestra si no hay errores.
+     */
+    private int DGNTestOpen(byte[] pabyHeader, int nByteCount) {
+        if (nByteCount < 4) {
+            return TRUE;
+        }
+
+        // Is it a cell library?
+        if ((pabyHeader[0] == (byte) 0x08) && (pabyHeader[1] == (byte) 0x05)
+                && (pabyHeader[2] == (byte) 0x17)
+                && (pabyHeader[3] == (byte) 0x00)) {
+            return TRUE;
+        }
+
+        // Is it not a regular 2D or 3D file?
+        if (((pabyHeader[0] != (byte) 0x08) && (pabyHeader[0] != (byte) 0xC8))
+                || (pabyHeader[1] != (byte) 0x09)
+                || (pabyHeader[2] != (byte) 0xFE)
+                || (pabyHeader[3] != (byte) 0x02)) {
+            return FALSE;
+        }
+
+        return TRUE;
+    }
+
+    /**
+     * Lee una fila del elemento.
+     *
+     * @param info Informaci�n del DGN.
+     * @param core Elemento.
+     *
+     * @return Devuelve un entero que muestra si se ha calculado correctamente.
+     */
+    private int DGNLoadRawElement(DGNInfo info, DGNElemCore core) {
+        /* -------------------------------------------------------------------- */
+        /* Read the first four bytes to get the level, type, and word */
+        /* count. */
+        /* -------------------------------------------------------------------- */
+
+        // int nType, nWords, nLevel;
+        int nType = 0;
+        int nWords = 0;
+        int nLevel = 0;
+        int bytesCount = 0;
+
+        try {
+            // input=new LEDataInputStream(fin);
+            for (int i = 0; i < 4; i++) {
+                info.abyElem[i] = bb.get();
+                if (i == 1) {
+                    if ((info.abyElem[0] == -1) && (info.abyElem[1] == -1)) {
+                        return FALSE;
+                    }
+                }
+
+                // info.temporal[i]=input.readByte();
+            }
+
+            nWords = ByteUtils.byteToUnsignedInt(info.abyElem[2])
+                    + (ByteUtils.byteToUnsignedInt(info.abyElem[3]) * 256);
+            nType = ByteUtils.byteToUnsignedInt(info.abyElem[1]) & 0x7f;
+            nLevel = ByteUtils.byteToUnsignedInt(info.abyElem[0]) & 0x3f;
+
+            /*
+             * ------------------------------------------------------------------
+             */
+            /* Read the rest of the element data into the working buffer. */
+            if (((nWords * 2) + 4) > info.abyElem.length) {
+                return FALSE;
+            }
+            for (; bytesCount < (nWords * 2) && bb.hasRemaining(); bytesCount++) {
+                info.abyElem[bytesCount + 4] = bb.get();
+            }
+            info.ftall = bb.position();
+        } catch (Exception e) {
+            logwarn(MessageFormat.format("The DGN file {0} may not be loaded correctly.\n"
+                    + "Error loading:\n"
+                    + "nWords = {1}\n"
+                    + "info.next_element_id {2}\n"
+                    + "info.abyElem.length =  {3}\n"
+                    + "bb.position() =  {4}",
+                    info.fp,
+                    nWords,
+                    info.next_element_id,
+                    info.abyElem.length,
+                    bb.position()), e);
+
+            return FALSE;
+        }
+
+        info.nElemBytes = bytesCount + 4;
+        info.next_element_id++;
+
+        /* -------------------------------------------------------------------- */
+        /* Return requested info. */
+        /* -------------------------------------------------------------------- */
+        core.type = nType;
+
+        core.level = nLevel;
+
+        return TRUE;
+    }
+
+    /**
+     * Calcula el filtro espacial al rect�ngulo del elemento.
+     *
+     * @param info Informaci�n del DGN.
+     */
+    private void DGNSpatialFilterToUOR(DGNInfo info) {
+        DGNPoint sMin = new DGNPoint();
+        DGNPoint sMax = new DGNPoint();
+
+        if ((info.sf_converted_to_uor == 1)
+                || (!(info.has_spatial_filter == 1)) || (!(info.got_tcb == 1))) {
+            return;
+        }
+
+        sMin.x = info.sf_min_x_geo;
+        sMin.y = info.sf_min_y_geo;
+        sMin.z = 0;
+
+        sMax.x = info.sf_max_x_geo;
+        sMax.y = info.sf_max_y_geo;
+        sMax.z = 0;
+
+        DGNInverseTransformPoint(info, sMin);
+        DGNInverseTransformPoint(info, sMax);
+
+        info.sf_min_x = (long) (sMin.x + 2147483648.0);
+        info.sf_min_y = (long) (sMin.y + 2147483648.0);
+        info.sf_max_x = (long) (sMax.x + 2147483648.0);
+        info.sf_max_y = (long) (sMax.y + 2147483648.0);
+
+        info.sf_converted_to_uor = TRUE;
+    }
+
+    /**
+     * Calcula un punto aplicandole la transformaci�n.
+     *
+     * @param info Informaci�n del DGN.
+     * @param punto Punto.
+     */
+    private void DGNInverseTransformPoint(DGNInfo info, DGNPoint punto) {
+        punto.x = (punto.x + info.origin_x) / info.scale;
+        punto.y = (punto.y + info.origin_y) / info.scale;
+        punto.z = (punto.z + info.origin_z) / info.scale;
+
+        punto.x = Math.max(-2147483647, Math.min(2147483647, punto.x));
+        punto.y = Math.max(-2147483647, Math.min(2147483647, punto.y));
+        punto.z = Math.max(-2147483647, Math.min(2147483647, punto.z));
+    }
+
+    public DGNElemCore DGNReadElement() {
+        DGNElemCore elemento = new DGNElemCore(this);
+        int nType;
+        int nLevel;
+        int bInsideFilter;
+
+        /* -------------------------------------------------------------------- */
+        /* Load the element data into the current buffer. If a spatial */
+        /* filter is in effect, loop until we get something within our */
+        /* spatial constraints. */
+        /* -------------------------------------------------------------------- */
+        do {
+            bInsideFilter = TRUE;
+
+            int fin_fichero = DGNLoadRawElement(info, elemento);
+
+            if (fin_fichero == FALSE) {
+                return null;
+            }
+
+            if (info.has_spatial_filter != FALSE) {
+                if (info.sf_converted_to_uor == FALSE) {
+                    DGNSpatialFilterToUOR(info);
+                }
+
+                if (DGNGetRawExtents(info, null, elemento) == null) {
+                    bInsideFilter = TRUE;
+                } else if ((info.min_x > info.sf_max_x)
+                        || (info.min_y > info.sf_max_y)
+                        || (info.max_x < info.sf_min_x)
+                        || (info.max_y < info.sf_min_y)) {
+                    bInsideFilter = FALSE;
+                }
+
+                if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)
+                        || (elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)) {
+                    info.in_complex_group = TRUE;
+                    info.select_complex_group = bInsideFilter;
+                } else if ((info.abyElem[0] & (byte) 0x80) != FALSE) {
+                    if (info.in_complex_group == TRUE) {
+                        bInsideFilter = info.select_complex_group;
+                    }
+                } else {
+                    info.in_complex_group = FALSE;
+                }
+            }
+        } while (bInsideFilter == FALSE);
+
+        elemento = DGNProcessElement(info, elemento.type, elemento.level);
+
+        return elemento;
+    }
+
+    /**
+     * Devuelve los extent de una fila.
+     *
+     * @param info Informaci�n del DGN.
+     * @param pabyRawData Vector de byte.
+     * @param elemento Elemento.
+     *
+     * @return Vector de double.
+     */
+    public double[] DGNGetRawExtents(DGNInfo info, byte[] pabyRawData,
+            DGNElemCore elemento) {
+        if (pabyRawData == null) {
+            pabyRawData = info.abyElem;
+        }
+
+        double[] tempo = new double[6];
+
+        switch (elemento.type) {
+            case DGNFileHeader.DGNT_LINE:
+            case DGNFileHeader.DGNT_LINE_STRING:
+            case DGNFileHeader.DGNT_SHAPE:
+            case DGNFileHeader.DGNT_CURVE:
+            case DGNFileHeader.DGNT_BSPLINE:
+            case DGNFileHeader.DGNT_ELLIPSE:
+            case DGNFileHeader.DGNT_ARC:
+            case DGNFileHeader.DGNT_TEXT:
+            case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
+            case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
+
+                byte[] temp = new byte[4];
+                System.arraycopy(pabyRawData, 4, temp, 0, 4);
+                tempo[0] = DGN_INT32(temp); // 4
+
+                System.arraycopy(pabyRawData, 8, temp, 0, 4);
+                tempo[1] = DGN_INT32(temp);
+
+                System.arraycopy(pabyRawData, 12, temp, 0, 4);
+                tempo[2] = DGN_INT32(temp);
+
+                System.arraycopy(pabyRawData, 16, temp, 0, 4);
+                tempo[3] = DGN_INT32(temp);
+
+                System.arraycopy(pabyRawData, 20, temp, 0, 4);
+                tempo[4] = DGN_INT32(temp);
+
+                System.arraycopy(pabyRawData, 24, temp, 0, 4);
+                tempo[5] = DGN_INT32(temp);
+
+                return tempo;
+
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * A partir de un vector de byte devuelve un double.
+     *
+     * @param p Vector de byte.
+     *
+     * @return double.
+     */
+    private double DGN_INT32(byte[] p) {
+        int x = 256;
+        int x0;
+        int x1;
+        int x2;
+        int x3;
+        x0 = p[0];
+        x1 = p[1];
+        x2 = p[2];
+        x3 = p[3];
+
+        if (p[0] < 0) {
+            x0 = x + p[0];
+        }
+
+        if (p[1] < 0) {
+            x1 = x + p[1];
+        }
+
+        if (p[2] < 0) {
+            x2 = x + p[2];
+        }
+
+        if (p[3] < 0) {
+            x3 = x + p[3];
+        }
+
+        return (x2 + (x3 * 256) + (x1 * 65536 * 256) + (x0 * 65536));
+    }
+
+    private DGNElemCore DGNProcessElement(DGNInfo info, int nType, int nLevel) {
+        DGNElemCore elemento = new DGNElemCore(this);
+
+        switch (nType) {
+            case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
+                logdebug("DGNProcessElement (DGNT_SHARED_CELL_DEFN): Type " + DGNTypeToName(nType));
+                elemento.stype = DGNFileHeader.DGNST_SHARED_CELL_DEFN;
+                DGNParseCore(info, elemento);
+
+                break;
+
+            case DGNFileHeader.DGNT_CELL_HEADER: {
+                DGNElemCellHeader psCell = new DGNElemCellHeader(this);
+                psCell.stype = DGNFileHeader.DGNST_CELL_HEADER;
+                DGNParseCore(info, psCell);
+                psCell.totlength = ByteUtils.getUnsigned(info.abyElem[36])
+                        + (ByteUtils.getUnsigned(info.abyElem[37]) * 256);
+
+                byte[] temp = new byte[psCell.name.length];
+                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
+                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[38])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256),
+                        temp);
+
+                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length - 3);
+
+                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[40])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256),
+                        temp);
+                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
+                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
+                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
+                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
+                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
+                psCell.color = info.abyElem[35];
+
+                if (info.dimension == 2) {
+                    byte[] temp1 = new byte[4];
+                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
+                    psCell.rnglow.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
+                    psCell.rnglow.y = DGN_INT32(temp);
+                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
+                    psCell.rnghigh.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
+                    psCell.rnghigh.y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 84, temp1, 0, 4);
+                    psCell.origin.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 88, temp1, 0, 4);
+                    psCell.origin.y = DGN_INT32(temp1);
+
+                    {
+                        double a;
+                        double b;
+                        double c;
+                        double d;
+                        double a2;
+                        double c2;
+                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
+                        a = DGN_INT32(temp1);
+                        System.arraycopy(info.abyElem, 72, temp1, 0, 4);
+                        b = DGN_INT32(temp1);
+                        System.arraycopy(info.abyElem, 76, temp1, 0, 4);
+                        c = DGN_INT32(temp1);
+                        System.arraycopy(info.abyElem, 80, temp1, 0, 4);
+                        d = DGN_INT32(temp1);
+                        a2 = a * a;
+                        c2 = c * c;
+                        psCell.xscale = Math.sqrt(a2 + c2) / 214748;
+                        psCell.yscale = Math.sqrt((b * b) + (d * d)) / 214748;
+                        psCell.rotation = Math.acos(a / Math.sqrt(a2 + c2));
+
+                        if (b <= 0) {
+                            psCell.rotation = (psCell.rotation * 180) / Math.PI;
+                        } else {
+                            psCell.rotation = 360 - ((psCell.rotation * 180) / Math.PI);
+                        }
+                    }
+                } else {
+                    byte[] temp1 = new byte[4];
+                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
+                    psCell.rnglow.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
+                    psCell.rnglow.y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
+                    psCell.rnglow.z = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
+                    psCell.rnghigh.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 68, temp1, 0, 4);
+                    psCell.rnghigh.y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 72, temp1, 0, 4);
+                    psCell.rnghigh.z = DGN_INT32(temp1);
+
+                    System.arraycopy(info.abyElem, 112, temp1, 0, 4);
+                    psCell.origin.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 116, temp1, 0, 4);
+                    psCell.origin.y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 120, temp1, 0, 4);
+                    psCell.origin.z = DGN_INT32(temp1);
+                }
+
+                DGNTransformPoint(info, psCell.rnglow);
+                DGNTransformPoint(info, psCell.rnghigh);
+                DGNTransformPoint(info, psCell.origin);
+                elemento = psCell;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_CELL_LIBRARY: {
+                logdebug("DGNProcessElement (DGNT_CELL_LIBRARY): Type " + DGNTypeToName(nType));
+
+                DGNElemCellLibrary psCell = new DGNElemCellLibrary(this);
+                int iWord;
+                psCell.stype = DGNFileHeader.DGNST_CELL_LIBRARY;
+                DGNParseCore(info, psCell);
+
+                byte[] temp = new byte[psCell.name.length];
+                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
+                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[32])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[33]) * 256),
+                        temp);
+                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length);
+                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[34])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[35]) * 256),
+                        temp);
+                psCell.properties = info.abyElem[38] + (info.abyElem[39] * 256);
+                psCell.dispsymb = ByteUtils.byteToUnsignedInt(info.abyElem[40])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256);
+                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
+                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
+                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
+                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
+                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
+                psCell.numwords = ByteUtils.byteToUnsignedInt(info.abyElem[36])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
+
+                for (iWord = 0; iWord < 9; iWord++) {
+                    int iOffset = 52 + (iWord * 2);
+                    System.arraycopy(psCell.name, iWord * 3, temp, 0,
+                            psCell.description.length);
+                    DGNRad50ToAscii(
+                            ByteUtils.byteToUnsignedInt(info.abyElem[iOffset])
+                            + (ByteUtils
+                            .byteToUnsignedInt(info.abyElem[iOffset + 1]) * 256),
+                            temp);
+                }
+
+                elemento = psCell;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_LINE: {
+                DGNElemMultiPoint psLine = new DGNElemMultiPoint(this);
+                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
+                DGNParseCore(info, psLine);
+                psLine.num_vertices = 2;
+                psLine.vertices = new DGNPoint[psLine.num_vertices];
+
+                if (info.dimension == 2) {
+                    byte[] temp1 = new byte[4];
+                    System.arraycopy(info.abyElem, 36, temp1, 0, 4);
+                    psLine.vertices[0] = new DGNPoint();
+                    psLine.vertices[0].x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
+                    psLine.vertices[0].y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 44, temp1, 0, 4);
+                    psLine.vertices[1] = new DGNPoint();
+                    psLine.vertices[1].x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 48, temp1, 0, 4);
+                    psLine.vertices[1].y = DGN_INT32(temp1);
+                } else {
+                    byte[] temp1 = new byte[4];
+                    System.arraycopy(info.abyElem, 36, temp1, 0, 4);
+                    psLine.vertices[0] = new DGNPoint();
+                    psLine.vertices[0].x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
+                    psLine.vertices[0].y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 44, temp1, 0, 4);
+                    psLine.vertices[0].z = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 48, temp1, 0, 4);
+                    psLine.vertices[1] = new DGNPoint();
+                    psLine.vertices[1].x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
+                    psLine.vertices[1].y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
+                    psLine.vertices[1].z = DGN_INT32(temp1);
+                }
+
+                DGNTransformPoint(info, psLine.vertices[0]);
+                DGNTransformPoint(info, psLine.vertices[1]);
+                elemento = psLine;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_LINE_STRING:
+            case DGNFileHeader.DGNT_SHAPE: // regular
+            case DGNFileHeader.DGNT_CURVE: // mal
+            case DGNFileHeader.DGNT_BSPLINE: // aceptable
+            {
+                DGNElemMultiPoint psLine = new DGNElemMultiPoint(this);
+                int i;
+                int count;
+                int pntsize = info.dimension * 4;
+
+                count = ByteUtils.byteToUnsignedInt(info.abyElem[36])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
+                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
+                DGNParseCore(info, psLine);
+
+                if (info.nElemBytes < (38 + (count * pntsize))) {
+                    logdebug("Error en los vertices de multipunto");
+                    count = (info.nElemBytes - 38) / pntsize;
+                    return null;
+                }
+
+                psLine.num_vertices = count;
+                psLine.vertices = new DGNPoint[psLine.num_vertices];
+
+                for (i = 0; i < psLine.num_vertices; i++) {
+                    byte[] temp1 = new byte[4];
+                    System.arraycopy(info.abyElem, 38 + (i * pntsize), temp1, 0, 4);
+                    psLine.vertices[i] = new DGNPoint();
+                    psLine.vertices[i].x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 42 + (i * pntsize), temp1, 0, 4);
+                    psLine.vertices[i].y = DGN_INT32(temp1);
+
+                    if (info.dimension == 3) {
+                        System.arraycopy(info.abyElem, 46 + (i * pntsize), temp1,
+                                0, 4);
+                        psLine.vertices[i].z = DGN_INT32(temp1);
+                    }
+
+                    DGNTransformPoint(info, psLine.vertices[i]);
+                }
+
+                elemento = psLine;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_GROUP_DATA:
+                if (nLevel == DGNFileHeader.DGN_GDL_COLOR_TABLE) {
+                    elemento = DGNParseColorTable(info);
+                } else {
+                    elemento.stype = DGNFileHeader.DGNST_CORE;
+                    DGNParseCore(info, elemento);
+                }
+                break;
+
+            case DGNFileHeader.DGNT_ELLIPSE: {
+                DGNElemArc psEllipse = new DGNElemArc(this);
+
+                psEllipse.stype = DGNFileHeader.DGNST_ARC;
+                DGNParseCore(info, psEllipse);
+
+                int[] fin = new int[1];
+                fin[0] = 0;
+
+                byte[] temp1 = new byte[8];
+                System.arraycopy(info.abyElem, 36, temp1, 0, 8);
+
+                fin[0] = 0;
+                psEllipse.primary_axis = DGNParseIEEE(temp1);
+
+                psEllipse.primary_axis *= info.scale;
+                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
+                fin[0] = 0;
+
+                psEllipse.secondary_axis = DGNParseIEEE(temp1);
+                psEllipse.secondary_axis *= info.scale;
+
+                if (info.dimension == 2) {
+                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
+                    psEllipse.rotation = DGN_INT32(temp1);
+                    psEllipse.rotation = psEllipse.rotation / 360000.0;
+                    System.arraycopy(info.abyElem, 56, temp1, 0, 8);
+                    fin[0] = 0;
+
+                    psEllipse.origin.x = DGNParseIEEE(temp1);
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 8);
+                    fin[0] = 0;
+
+                    psEllipse.origin.y = DGNParseIEEE(temp1);
+                } else {
+                    // leave quaternion for later
+                    System.arraycopy(info.abyElem, 68, temp1, 0, 8);
+                    fin[0] = 0;
+                    psEllipse.origin.x = DGNParseIEEE(temp1);
+
+                    System.arraycopy(info.abyElem, 76, temp1, 0, 8);
+                    fin[0] = 0;
+                    psEllipse.origin.y = DGNParseIEEE(temp1);
+
+                    System.arraycopy(info.abyElem, 84, temp1, 0, 8);
+                    fin[0] = 0;
+                    psEllipse.origin.z = DGNParseIEEE(temp1);
+
+                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
+                    psEllipse.quat[0] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
+                    psEllipse.quat[1] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
+                    psEllipse.quat[2] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
+                    psEllipse.quat[3] = DGN_INT32(temp1);
+                }
+
+                DGNTransformPoint(info, (psEllipse.origin));
+
+                psEllipse.startang = 0.0;
+                psEllipse.sweepang = 360.0;
+                elemento = psEllipse;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_ARC: {
+                DGNElemArc psEllipse = new DGNElemArc(this);
+                double nSweepVal;
+
+                psEllipse.stype = DGNFileHeader.DGNST_ARC;
+                DGNParseCore(info, psEllipse);
+
+                int[] fin = new int[1];
+                fin[0] = 0;
+
+                byte[] temp1 = new byte[8];
+                System.arraycopy(info.abyElem, 36, temp1, 0, 4);
+                psEllipse.startang = DGN_INT32(temp1);
+                psEllipse.startang = psEllipse.startang / 360000.0;
+
+                if ((info.abyElem[41] & (byte) 0x80) != FALSE) {
+                    info.abyElem[41] &= (byte) 0x7f;
+                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
+                    nSweepVal = -1 * DGN_INT32(temp1);
+                } else {
+                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
+                    nSweepVal = DGN_INT32(temp1);
+                }
+
+                if (nSweepVal == 0) {
+                    psEllipse.sweepang = 360.0;
+                } else {
+                    psEllipse.sweepang = nSweepVal / 360000.0;
+                }
+
+                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
+                fin[0] = 0;
+                psEllipse.primary_axis = DGNParseIEEE(temp1);
+
+                psEllipse.primary_axis *= info.scale;
+                System.arraycopy(info.abyElem, 52, temp1, 0, 8);
+                fin[0] = 0;
+                psEllipse.secondary_axis = DGNParseIEEE(temp1);
+
+                psEllipse.secondary_axis *= info.scale;
+
+                if (info.dimension == 2) {
+                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
+                    psEllipse.rotation = DGN_INT32(temp1);
+                    psEllipse.rotation = psEllipse.rotation / 360000.0;
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 8);
+                    fin[0] = 0;
+                    psEllipse.origin.x = DGNParseIEEE(temp1);
+
+                    System.arraycopy(info.abyElem, 72, temp1, 0, 8);
+                    fin[0] = 0;
+                    psEllipse.origin.y = DGNParseIEEE(temp1);
+                } else {
+                    // for now we don't try to handle quaternion
+                    psEllipse.rotation = 0;
+                    System.arraycopy(info.abyElem, 76, temp1, 0, 8);
+                    fin[0] = 0;
+
+                    psEllipse.origin.x = DGNParseIEEE(temp1);
+                    System.arraycopy(info.abyElem, 84, temp1, 0, 8);
+                    fin[0] = 0;
+
+                    psEllipse.origin.y = DGNParseIEEE(temp1);
+                    System.arraycopy(info.abyElem, 92, temp1, 0, 8);
+                    fin[0] = 0;
+
+                    psEllipse.origin.z = DGNParseIEEE(temp1);
+                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
+                    psEllipse.quat[0] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
+                    psEllipse.quat[1] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 68, temp1, 0, 4);
+                    psEllipse.quat[2] = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 72, temp1, 0, 4);
+                    psEllipse.quat[3] = DGN_INT32(temp1);
+                }
+
+                DGNTransformPoint(info, (psEllipse.origin));
+                elemento = psEllipse;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_TEXT: {
+                DGNElemText psText = new DGNElemText(this);
+                int num_chars;
+                int text_off;
+
+                if (info.dimension == 2) {
+                    num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[58]);
+                } else {
+                    num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[74]);
+                }
+
+                psText.stype = DGNFileHeader.DGNST_TEXT;
+                DGNParseCore(info, psText);
+
+                psText.font_id = ByteUtils.byteToUnsignedInt(info.abyElem[36]);
+                psText.justification = ByteUtils
+                        .byteToUnsignedInt(info.abyElem[37]);
+
+                byte[] temp1 = new byte[8];
+                System.arraycopy(info.abyElem, 38, temp1, 0, 4);
+                psText.length_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
+                System.arraycopy(info.abyElem, 42, temp1, 0, 4);
+                psText.height_raw = DGN_INT32(temp1);
+                psText.height_mult = (psText.height_raw * info.scale * 6.0) / 1000.0;
+
+                int[] fin = new int[1];
+                fin[0] = 0;
+
+                if (info.dimension == 2) {
+                    System.arraycopy(info.abyElem, 46, temp1, 0, 4);
+                    psText.rotation = DGN_INT32(temp1);
+                    psText.rotation = psText.rotation / 360000.0;
+                    System.arraycopy(info.abyElem, 50, temp1, 0, 4);
+                    psText.origin.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 54, temp1, 0, 4);
+                    psText.origin.y = DGN_INT32(temp1);
+                    text_off = 60;
+                } else {
+                    /* leave quaternion for later */
+                    System.arraycopy(info.abyElem, 62, temp1, 0, 4);
+                    psText.origin.x = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 66, temp1, 0, 4);
+                    psText.origin.y = DGN_INT32(temp1);
+                    System.arraycopy(info.abyElem, 70, temp1, 0, 4);
+                    psText.origin.z = DGN_INT32(temp1);
+                    text_off = 76;
+                }
+
+                DGNTransformPoint(info, (psText.origin));
+
+                // TODO: AQUI FALTA METER ALGO PARA SOPORTAR TEXTOS MULTYBYTE
+                byte[] temp = new byte[num_chars];
+                System.arraycopy(info.abyElem, text_off, temp, 0, num_chars);
+
+                String strAux = null;
+
+                try {
+                    psText.string = new String(temp, "ISO-8859-1");
+                } catch (Exception e) {
+                    logwarn("Can't create java string from byte array (" + dumpBuffer(temp) + ").", e);
+                }
+
+                elemento = psText;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_TCB:
+                if (info.got_tcb == FALSE) {
+                    elemento = DGNParseTCB(info);
+                    elemento.level = nLevel;
+                    elemento.type = nType;
+                }
+                break;
+
+            case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
+            case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER: {
+                DGNElemComplexHeader psHdr = new DGNElemComplexHeader(this);
+
+                psHdr.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
+                DGNParseCore(info, psHdr);
+
+                psHdr.totlength = ByteUtils.byteToUnsignedInt(info.abyElem[36])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
+                psHdr.numelems = ByteUtils.byteToUnsignedInt(info.abyElem[38])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256);
+                elemento = psHdr;
+            }
+
+            break;
+
+            case DGNFileHeader.DGNT_TAG_VALUE: {
+                DGNElemTagValue psTag = new DGNElemTagValue(this);
+
+                psTag.stype = DGNFileHeader.DGNST_TAG_VALUE;
+                DGNParseCore(info, psTag);
+
+                int[] fin = new int[1];
+                fin[0] = 0;
+
+                byte[] temp1 = new byte[8];
+                psTag.tagType = ByteUtils.byteToUnsignedInt(info.abyElem[74])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[75]) * 256);
+                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
+                fin[0] = 0;
+                psTag.tagSet = ByteUtils.bytesToInt(temp1, fin);
+
+                psTag.tagSet = CPL_LSBWORD32(psTag.tagSet);
+                psTag.tagIndex = ByteUtils.byteToUnsignedInt(info.abyElem[72])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[73]) * 256);
+                psTag.tagLength = ByteUtils.byteToUnsignedInt(info.abyElem[150])
+                        + (ByteUtils.byteToUnsignedInt(info.abyElem[151]) * 256);
+
+                if (psTag.tagType == 1) {
+                    byte[] temp = new byte[info.abyElem.length - 154];
+                    System.arraycopy(info.abyElem, 4, temp1, 0, // 154
+                            4); // info.abyElem.length - 154
+                    fin[0] = 0;
+                    psTag.tagValue.string = ByteUtils.bytesToString(temp1, fin).toCharArray();
+                } else if (psTag.tagType == 3) {
+                    byte[] temp = new byte[4];
+                    System.arraycopy(info.abyElem, 154, temp1, 0, 4);
+                    fin[0] = 0;
+                    psTag.tagValue.integer = ByteUtils.bytesToInt(temp1, fin);
+
+                    psTag.tagValue.integer = CPL_LSBWORD32((int) psTag.tagValue.integer);
+                } else if (psTag.tagType == 4) {
+                    byte[] temp = new byte[8];
+                    System.arraycopy(info.abyElem, 154, temp1, 0, 8);
+                    fin[0] = 0;
+                    psTag.tagValue.real = DGNParseIEEE(temp1);
+                }
+
+                elemento = psTag;
+            }
+
+            break;
+
+            default: {
+                elemento.stype = DGNFileHeader.DGNST_CORE;
+                DGNParseCore(info, elemento);
+            }
+
+            break;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* If the element structure type is "core" or if we are running */
+        /* in "capture all" mode, record the complete binary image of */
+        /* the element. */
+        /* -------------------------------------------------------------------- */
+        if ((elemento.stype == DGNFileHeader.DGNST_CORE)
+                || ((info.options & DGNFileHeader.DGNO_CAPTURE_RAW_DATA) != FALSE)) {
+            elemento.raw_bytes = info.nElemBytes;
+
+            elemento.raw_data = new byte[elemento.raw_bytes];
+
+            int[] fin = new int[1];
+            fin[0] = 0;
+            System.arraycopy(info.abyElem, 0, elemento.raw_data, 0,
+                    elemento.raw_bytes);
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Collect some additional generic information. */
+        /* -------------------------------------------------------------------- */
+        elemento.element_id = info.next_element_id - 1;
+
+        elemento.offset = info.ftall - info.nElemBytes;
+        elemento.size = info.nElemBytes;
+        return elemento;
+    }
+
+    private String numberFormat(String fmt, byte number) {
+        Formatter out = new Formatter();
+        return out.format(fmt, number).toString();
+    }
+
+    private String numberFormat(String fmt, int number) {
+        Formatter out = new Formatter();
+        return out.format(fmt, number).toString();
+    }
+
+    private String numberFormat(String fmt, double number) {
+        Formatter out = new Formatter();
+        return out.format(fmt, number).toString();
+    }
+
+    private String dumpBuffer(byte[] buffer) {
+        StringBuffer out = new StringBuffer();
+        StringBuffer out1 = new StringBuffer();
+        Formatter out2 = new Formatter();
+
+        int n = 0;
+        for (int i = 0; i < buffer.length; i++) {
+            int ch = buffer[i] & 0xff;
+            if (Character.isLetterOrDigit(ch)) {
+                out1.append(Character.valueOf((char) ch));
+            } else {
+                out1.append("-");
+            }
+            out2.format("0x%02X ", ch);
+            if (++n >= 8) {
+                n = 0;
+                out.append(out1);
+                out.append("|");
+                out.append(out2);
+                out.append("\n");
+                out1 = new StringBuffer();
+                out2 = new Formatter();
+            }
+        }
+        if (out1.length() > 0) {
+            out.append(out1);
+            out.append("|");
+            out.append(out2);
+            out.append("\n");
+        }
+        return out.toString();
+    }
+
+    private double DGNParseIEEE(double d) {
+        byte[] temp = new byte[8];
+        int[] f = {0};
+        ByteUtils.doubleToBytes(d, temp, f);
+
+        return DGNParseIEEE(temp);
+    }
+
+    private double DGNParseIEEE(byte[] b) {
+        byte BYTE2 = b[7];
+        byte BYTE3 = b[6];
+        byte BYTE0 = b[5];
+        byte BYTE1 = b[4];
+        byte BYTE6 = b[3];
+        byte BYTE7 = b[2];
+        byte BYTE4 = b[1];
+        byte BYTE5 = b[0];
+        int sign;
+        int exponent;
+        int fraction;
+        double value;
+        int hi;
+        int lo;
+        int rndbits;
+
+        /* -------------------------------------------------------------------- */
+        /* Save the sign of the double */
+        /* -------------------------------------------------------------------- */
+        byte[] temp = new byte[4];
+        byte[] temp1 = new byte[4];
+
+        temp[3] = BYTE7;
+        temp[2] = BYTE6;
+        temp[1] = BYTE5;
+        temp[0] = BYTE4;
+
+        int[] f = {0};
+        hi = ByteUtils.bytesToInt(temp, f);
+        sign = hi & 0x80000000;
+
+        /* -------------------------------------------------------------------- */
+        /* Adjust the exponent so that we may work with it */
+        /* -------------------------------------------------------------------- */
+        exponent = hi >> 23;
+        exponent = exponent & 0x000000ff;
+
+        if (exponent != 0) {
+            exponent = exponent - 129 + 1023;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Save the bits that we are discarding so we can round properly */
+        /* -------------------------------------------------------------------- */
+        temp[3] = BYTE3;
+        temp[2] = BYTE2;
+        temp[1] = BYTE1;
+        temp[0] = BYTE0;
+
+        f[0] = 0;
+        lo = ByteUtils.bytesToInt(temp, f);
+        rndbits = lo & 0x00000007;
+
+        lo = lo >> 3;
+        lo = (lo & 0x1fffffff) | (hi << 29);
+
+        if (rndbits != 0) {
+            lo = lo | 0x00000001;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Shift the hi-order int over 3 and insert the exponent and sign */
+        /* -------------------------------------------------------------------- */
+        hi = hi >> 3;
+        hi = hi & 0x000fffff;
+        hi = hi | (exponent << 20) | sign;
+        f[0] = 0;
+        ByteUtils.intToBytes(hi, temp, f);
+        f[0] = 0;
+        ByteUtils.intToBytes(lo, temp1, f);
+
+        byte[] result = new byte[8];
+        result[7] = temp1[3];
+        result[6] = temp1[2];
+        result[5] = temp1[1];
+        result[4] = temp1[0];
+        result[3] = temp[3];
+        result[2] = temp[2];
+        result[1] = temp[1];
+        result[0] = temp[0];
+
+        f[0] = 0;
+
+        value = ByteUtils.bytesToDouble(result, f);
+
+        return value;
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGN2IEEEDouble() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Cambia el double a IEEDouble.
+     *
+     * @param dbl double de entrada.
+     */
+    private double DGN2IEEEDouble(double dbl) {
+        int tempInt = (int) Double.doubleToLongBits(dbl);
+        int low = (tempInt & 0xffff0000) >>> 16; // >>>: Right shift without
+        // sign extension
+        int high = (tempInt & 0x0000ffff) << 16;
+        tempInt = high | low;
+        int s = ((tempInt >> 31) == 0) ? 1 : -1;
+        int e = ((tempInt >> 23) & 0xff);
+        int m = (tempInt & 0x7fffff) | 0x800000;
+        return ((s * m * 2 * Math.pow(2, e - 128 - 25)));
+    }
+
+    private double IEEE2DGNDouble(double dbl) {
+        double64 dt = new double64();
+
+        dt.hi = 0;
+        dt.lo = 0;
+
+        long sign;
+        long exponent;
+        long rndbits;
+        byte[] srclo = new byte[4];
+        byte[] srchi = new byte[4];
+        byte[] destlo = new byte[4];
+        byte[] desthi = new byte[4];
+        byte[] src = new byte[8];
+        byte[] dest = new byte[8];
+
+        for (int i = 0; i < 8; i++) {
+            src[i] = '0';
+            dest[i] = '0';
+        }
+
+        int[] fin = new int[1];
+
+        if (LSB == TRUE) {
+            fin[0] = 0;
+            ByteUtils.doubleToBytes(dbl, src, fin);
+            dest[0] = src[4];
+            dest[1] = src[5];
+            dest[2] = src[6];
+            dest[3] = src[7];
+            dest[4] = src[0];
+            dest[5] = src[1];
+            dest[6] = src[2];
+            dest[7] = src[3];
+        } else {
+            // memcpy( &dt, dbl, 8 );
+        }
+
+        sign = dt.hi & 0x80000000;
+        exponent = dt.hi >> 20;
+        exponent = exponent & 0x000007ff;
+
+        /* -------------------------------------------------------------------- */
+        /* An exponent of zero means a zero value. */
+        /* -------------------------------------------------------------------- */
+        if (exponent != FALSE) {
+            exponent = exponent - 1023 + 129;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* In the case of overflow, return the largest number we can */
+        /* -------------------------------------------------------------------- */
+        if (exponent > 255) {
+            fin[0] = 0;
+            ByteUtils.doubleToBytes(dbl, dest, fin);
+
+            if (sign != FALSE) {
+                dest[1] = 0xf;
+            } else {
+                dest[1] = 0x7f;
+            }
+
+            dest[0] = 0xf;
+            dest[2] = 0xf;
+            dest[3] = 0xf;
+            dest[4] = 0xf;
+            dest[5] = 0xf;
+            dest[6] = 0xf;
+            dest[7] = 0xf;
+
+            return ByteUtils.bytesToDouble(dest, new int[0]);
+        } /* -------------------------------------------------------------------- */ /* In the case of of underflow return zero */ /* -------------------------------------------------------------------- */ else if ((exponent < 0) || ((exponent == 0) && (sign == 0))) {
+            fin[0] = 0;
+            ByteUtils.doubleToBytes(dbl, dest, fin);
+            dest[0] = 0x00;
+            dest[1] = 0x00;
+            dest[2] = 0x00;
+            dest[3] = 0x00;
+            dest[4] = 0x00;
+            dest[5] = 0x00;
+            dest[6] = 0x00;
+            dest[7] = 0x00;
+
+            return 0.0;
+        } else {
+            /* Shift the fraction 3 bits left and set the exponent and sign */
+            /*
+             * ------------------------------------------------------------------
+             */
+            System.arraycopy(dest, 0, destlo, 0, 4);
+            fin[0] = 0;
+            dt.lo = ByteUtils.bytesToLong(destlo, fin);
+            System.arraycopy(dest, 4, desthi, 0, 4);
+            fin[0] = 0;
+            dt.hi = ByteUtils.bytesToLong(desthi, fin);
+
+            dt.hi = dt.hi << 3;
+            dt.hi = dt.hi | (dt.lo >> 29);
+            dt.hi = dt.hi & 0x007fffff;
+            dt.hi = dt.hi | (exponent << 23) | sign;
+
+            dt.lo = dt.lo << 3;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Convert the double back to VAX format */
+        /* -------------------------------------------------------------------- */
+        fin[0] = 0;
+
+        ByteUtils.longToBytes(dt.lo, srclo, fin);
+
+        fin[0] = 0;
+        ByteUtils.longToBytes(dt.hi, srchi, fin);
+
+        if (LSB == TRUE) {
+            dest[2] = srclo[0];
+            dest[3] = srclo[1];
+            dest[0] = srclo[2];
+            dest[1] = srclo[3];
+            dest[6] = srchi[0];
+            dest[7] = srchi[1];
+            dest[4] = srchi[2];
+            dest[5] = srchi[3];
+        } else {
+            dest[1] = srclo[0];
+            dest[0] = srclo[1];
+            dest[3] = srclo[2];
+            dest[2] = srclo[3];
+            dest[5] = srchi[0];
+            dest[4] = srchi[1];
+            dest[7] = srchi[2];
+            dest[6] = srchi[3];
+        }
+
+        fin[0] = 0;
+        dbl = ByteUtils.bytesToDouble(dest, fin);
+        return dbl;
+
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGNElemTypeHasDispHdr() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Does element type have display header.
+     *
+     * @param nElemType element type (0-63) to test.
+     *
+     * @return TRUE if elements of passed in type have a display header after
+     * the core element header, or FALSE otherwise.
+     */
+    private int DGNElemTypeHasDispHdr(int nElemType) {
+        switch (nElemType) {
+            case 0:
+            case DGNFileHeader.DGNT_TCB:
+            case DGNFileHeader.DGNT_CELL_LIBRARY:
+            case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
+            case 32:
+            case 44:
+            case 48:
+            case 49:
+            case 50:
+            case 51:
+            case 57:
+            case 63:
+                return FALSE;
+
+            default:
+                return TRUE;
+        }
+    }
+
+    private int DGNParseCore(DGNInfo info, DGNElemCore elemento) {
+        byte[] psData = info.abyElem; // 0
+
+        elemento.level = psData[0] & (byte) 0x3f;
+        elemento.complex = psData[0] & (byte) 0x80;
+        elemento.deleted = psData[1] & (byte) 0x80;
+        elemento.type = psData[1] & (byte) 0x7f;
+
+        if ((info.nElemBytes >= 36)
+                && (DGNElemTypeHasDispHdr(elemento.type) == TRUE)) {
+            elemento.graphic_group = psData[28] + (psData[29] * 256);
+            elemento.properties = psData[32] + (psData[33] * 256);
+
+            elemento.style = psData[34] & (byte) 0x7;
+            elemento.weight = (psData[34] & (byte) 0xf8) >> 3;
+
+            byte aux = psData[35];
+
+            elemento.color = ByteUtils.getUnsigned(aux);
+
+        } else {
+            elemento.graphic_group = 0;
+            elemento.properties = 0;
+            elemento.style = 0;
+            elemento.weight = 0;
+            elemento.color = 0;
+        }
+
+        if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
+            int nAttIndex;
+
+            nAttIndex = ByteUtils.getUnsigned(psData[30])
+                    + (ByteUtils.getUnsigned(psData[31]) * 256);
+
+            int numBytes = info.nElemBytes - (nAttIndex * 2) - 32;
+
+            if ((numBytes > 0)) {
+                // Como m�ximo guardamos 10 bytes (Total, lo queremos para el
+                // color....
+                // if (numBytes > 10) numBytes = 10;
+                elemento.attr_bytes = numBytes;
+
+                elemento.attr_data = new byte[elemento.attr_bytes];
+
+                System.arraycopy(psData, (nAttIndex * 2) + 32,
+                        elemento.attr_data, 0, elemento.attr_bytes);
+            }
+        }
+
+        return TRUE;
+    }
+
+    private void DGNRad50ToAscii(int rad50, byte[] str) {
+        byte cTimes;
+        int value;
+        int temp;
+        byte ch = '\0';
+        int i = 0;
+
+        while (rad50 > 0) {
+            value = rad50;
+            cTimes = 0;
+
+            while (value >= 40) {
+                value /= 40;
+                cTimes++;
+            }
+
+            byte[] abc = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+                'W', 'X', 'Y', 'Z'};
+            byte[] num = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+            /* Map 0..39 to ASCII */
+            if (value == 0) {
+                ch = ' '; /* space */
+
+            } else if ((value >= 1) && (value <= 26)) {
+                ch = abc[value - 1]; /* printable alpha A..Z */
+
+            } else if (value == 27) {
+                ch = '$'; /* dollar */
+
+            } else if (value == 28) {
+                ch = '.'; /* period */
+
+            } else if (value == 29) {
+                ch = ' '; /* unused char, emit a space instead */
+
+            } else if ((value >= 30) && (value <= 39)) {
+                try {
+                    ch = num[value - 30]; /* digit 0..9 */
+
+                } catch (Exception ex) {
+                    logwarn("Invalid char in rad50 conversion, asume blank (rad50=" + rad50 + ", value=" + value + ".", ex);
+                    ch = ' ';
+                }
+            }
+
+            str[i] = ch;
+            i++;
+
+            temp = 1;
+
+            while (cTimes-- > 0) {
+                temp *= 40;
+            }
+
+            rad50 -= (value * temp);
+        }
+
+        /* Do zero-terminate */
+        str[i] = '\0';
+    }
+
+    /**
+     * Transforma el punto.
+     *
+     * @param info Informaci�n del DGN.
+     * @param psPoint Punto.
+     */
+    private void DGNTransformPoint(DGNInfo info, DGNPoint psPoint) {
+        psPoint.x = (psPoint.x * info.scale) - info.origin_x;
+        psPoint.y = (psPoint.y * info.scale) - info.origin_y;
+        psPoint.z = (psPoint.z * info.scale) - info.origin_z;
+    }
+
+    private DGNElemCore DGNParseColorTable(DGNInfo psDGN) {
+        DGNElemColorTable psColorTable = new DGNElemColorTable(this);
+
+        psColorTable.stype = DGNFileHeader.DGNST_COLORTABLE;
+
+        DGNParseCore(psDGN, psColorTable);
+
+        psColorTable.screen_flag = ByteUtils
+                .byteToUnsignedInt(psDGN.abyElem[36])
+                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[37]) * 256);
+
+        int[] fin = new int[1];
+        fin[0] = 0;
+
+        byte[] temp = new byte[3];
+        System.arraycopy(psDGN.abyElem, 38, temp, 0, 3);
+        psColorTable.color_info[255] = temp;
+
+        byte[] temp2 = new byte[765];
+        System.arraycopy(psDGN.abyElem, 41, temp2, 0, 765);
+
+        int k = 0;
+
+        logdebug("Color table");
+        logdebug("==============");
+        for (int i = 0; i < 255; i++) {
+            for (int j = 0; j < 3; j++) {
+                psColorTable.color_info[i][j] = temp2[k];
+                k++;
+            }
+            logdebug("Color[" + i + "] {"
+                    + psColorTable.color_info[i][0] + ", "
+                    + psColorTable.color_info[i][1] + ", "
+                    + psColorTable.color_info[i][2] + "}"
+            );
+        }
+
+        if (psDGN.got_color_table == FALSE) {
+            psDGN.color_table = psColorTable.color_info;
+            psDGN.got_color_table = 1;
+        }
+
+        return psColorTable;
+    }
+
+    private DGNElemCore DGNParseTCB(DGNInfo psDGN) {
+        DGNElemTCB psTCB = new DGNElemTCB(this);
+        int iView;
+        int[] fin = new int[1];
+        psTCB.stype = DGNFileHeader.DGNST_TCB;
+        DGNParseCore(psDGN, psTCB);
+
+        if ((psDGN.abyElem[1214] & (byte) 0x40) != FALSE) {
+            psTCB.dimension = 3;
+        } else {
+            psTCB.dimension = 2;
+        }
+
+        // psTCB.dimension = 3;
+        fin[0] = 0;
+
+        byte[] temp1 = new byte[8];
+        System.arraycopy(psDGN.abyElem, 1112, temp1, 0, 4);
+        psTCB.subunits_per_master = DGN_INT32(temp1);
+
+        psTCB.master_units[0] = (char) (psDGN.abyElem[1120]);
+        psTCB.master_units[1] = (char) (psDGN.abyElem[1121]);
+        psTCB.master_units[2] = '\0';
+
+        System.arraycopy(psDGN.abyElem, 1116, temp1, 0, 4);
+        psTCB.uor_per_subunit = DGN_INT32(temp1);
+
+        psTCB.sub_units[0] = (char) (psDGN.abyElem[1122]);
+        psTCB.sub_units[1] = (char) (psDGN.abyElem[1123]);
+        psTCB.sub_units[2] = '\0';
+
+        /* Get global origin */
+        System.arraycopy(psDGN.abyElem, 1240, temp1, 0, 8);
+        ByteBuffer buffer = ByteBuffer.wrap(psDGN.abyElem);
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+        psTCB.origin_x = buffer.getDouble(1240);
+        psTCB.origin_y = buffer.getDouble(1248);
+        psTCB.origin_z = buffer.getDouble(1256);
+
+        /* Transform to IEEE */
+        psTCB.origin_x = DGN2IEEEDouble(psTCB.origin_x);
+        psTCB.origin_y = DGN2IEEEDouble(psTCB.origin_y);
+        psTCB.origin_z = DGN2IEEEDouble(psTCB.origin_z);
+
+        /* Convert from UORs to master units. */
+        if ((psTCB.uor_per_subunit != 0) && (psTCB.subunits_per_master != 0)) {
+            psTCB.origin_x = psTCB.origin_x
+                    / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
+            psTCB.origin_y = psTCB.origin_y
+                    / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
+            psTCB.origin_z = psTCB.origin_z
+                    / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
+        }
+
+        // psDGN.dimension = psTCB.dimension;
+        if (psDGN.got_tcb == FALSE) {
+            psDGN.got_tcb = TRUE;
+
+            psDGN.origin_x = psTCB.origin_x;
+            psDGN.origin_y = psTCB.origin_y;
+            psDGN.origin_z = psTCB.origin_z;
+            if ((psTCB.uor_per_subunit != 0)
+                    && (psTCB.subunits_per_master != 0)) {
+                psDGN.scale = 1.0 / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
+            }
+        }
+
+        logdebug("Datos del TCB: " + psTCB.origin_x + " " + psTCB.origin_y);
+        logdebug("psTCB.uor_per_subunit: " + psTCB.uor_per_subunit);
+        logdebug("psTCB.subunits_per_master: " + psTCB.subunits_per_master);
+        logdebug("psTCB.origen = " + psTCB.origin_x + " " + psTCB.origin_y);
+        logdebug("psDGN.scale = " + psDGN.scale);
+        logdebug("psDGN.origen = " + psDGN.origin_x + " " + psDGN.origin_y);
+        logdebug("psDGN.dimension = " + psDGN.dimension);
+
+        /* Collect views */
+        for (iView = 0; iView < 8; iView++) {
+            byte[] pabyRawView = new byte[psDGN.abyElem.length];
+            fin[0] = 0;
+            System.arraycopy(psDGN.abyElem, (46 + (iView * 118)), pabyRawView,
+                    0, psDGN.abyElem.length - (46 + (iView * 118)));
+
+            psTCB.views[iView] = new DGNViewInfo();
+            psTCB.views[iView].flags = ByteUtils
+                    .byteToUnsignedInt(pabyRawView[0])
+                    + (ByteUtils.byteToUnsignedInt(pabyRawView[1]) * 256);
+
+            byte[] temp2 = new byte[4];
+            int f = 0;
+
+            for (int j = 0; j < 8; j++) {
+                System.arraycopy(pabyRawView, j + 2, temp2, 0, 1);
+                fin[0] = 0;
+                psTCB.views[iView].levels[f] = temp2[0];
+                f++;
+            }
+
+            psTCB.views[iView].origin = new DGNPoint();
+            System.arraycopy(pabyRawView, 10, temp1, 0, 4);
+            psTCB.views[iView].origin.x = DGN_INT32(temp1);
+
+            System.arraycopy(pabyRawView, 14, temp1, 0, 4);
+            psTCB.views[iView].origin.y = DGN_INT32(temp1);
+            System.arraycopy(pabyRawView, 18, temp1, 0, 4);
+            psTCB.views[iView].origin.z = DGN_INT32(temp1);
+            DGNTransformPoint(psDGN, (psTCB.views[iView].origin));
+
+            psTCB.views[iView].delta = new DGNPoint();
+            System.arraycopy(pabyRawView, 22, temp1, 0, 4);
+            psTCB.views[iView].delta.x = DGN_INT32(temp1);
+            System.arraycopy(pabyRawView, 26, temp1, 0, 4);
+            psTCB.views[iView].delta.y = DGN_INT32(temp1);
+            System.arraycopy(pabyRawView, 30, temp1, 0, 4);
+            psTCB.views[iView].delta.z = DGN_INT32(temp1);
+
+            psTCB.views[iView].delta.x *= psDGN.scale;
+            psTCB.views[iView].delta.y *= psDGN.scale;
+            psTCB.views[iView].delta.z *= psDGN.scale;
+
+            psTCB.views[iView].transmatrx = new double[9];
+
+            for (int k = 0; k < 9; k++) {
+                System.arraycopy(pabyRawView, (34 + (8 * k)), temp1, 0, 8);
+
+                fin[0] = 0;
+                psTCB.views[iView].transmatrx[k] = DGNParseIEEE(temp1);
+            }
+
+            System.arraycopy(pabyRawView, 106, temp1, 0, 8);
+            fin[0] = 0;
+            psTCB.views[iView].conversion = ByteUtils.bytesToLong(temp1, fin);
+            fin[0] = 0;
+            psTCB.views[iView].conversion = ByteUtils.bytesToDouble(temp1, fin);
+
+            DGNParseIEEE(psTCB.views[iView].conversion);
+            System.arraycopy(pabyRawView, 114, temp1, 0, 8);
+            psTCB.views[iView].activez = DGN_INT32(temp1);
+        }
+        return psTCB;
+    }
+
+    /**
+     * Cambia un entero a LitterIndian.
+     *
+     * @param x Entero de entrada.
+     *
+     * @return Entero de salida.
+     */
+    private int CPL_LSBWORD32(int x) {
+        return (((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)
+                | (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24)));
+    }
+
+    /**
+     * Cambia el vector de char de entrada en el caso de ser null por el
+     * caracter vacio.
+     *
+     * @param pszString Vector de char.
+     *
+     * @return Vector de char.
+     */
+//    private char[] CPLStrdup(char[] pszString) {
+//        char[] pszReturn;
+//
+//        if (pszString == null) {
+//            pszString[0] = ' ';
+//        }
+//        pszReturn = new char[pszString.length];
+//        pszReturn = pszString;
+//        if (pszReturn == null) {
+//            logwarn("error");
+//        }
+//        return (pszReturn);
+//    }
+    private DGNElemCore DGNParseTagSet(DGNInfo psDGN) {
+
+        DGNElemTagSet psTagSet = new DGNElemTagSet(this);
+        int nDataOffset;
+        int iTag;
+
+        psTagSet.stype = DGNFileHeader.DGNST_TAG_SET;
+
+        DGNParseCore(psDGN, psTagSet);
+
+        /* -------------------------------------------------------------------- */
+        /* Parse the overall information. */
+        /* -------------------------------------------------------------------- */
+        psTagSet.tagCount = ByteUtils.byteToUnsignedInt(psDGN.abyElem[44])
+                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[45]) * 256);
+        psTagSet.flags = ByteUtils.byteToUnsignedInt(psDGN.abyElem[46])
+                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[47]) * 256);
+
+        int[] fin = new int[1];
+        fin[0] = 0;
+
+        byte[] temp = new byte[elemento.attr_bytes];
+        System.arraycopy(psDGN.abyElem, 48, temp, 0, psDGN.abyElem.length - 48);
+
+        psTagSet.tagSetName = ByteUtils.bytesToString(temp, fin).toCharArray();
+
+        /* -------------------------------------------------------------------- */
+        /* Get the tag set number out of the attributes, if available. */
+        /* -------------------------------------------------------------------- */
+        psTagSet.tagSet = -1;
+
+        if ((psTagSet.attr_bytes >= 8)
+                && (psTagSet.attr_data[0] == (byte) 0x03)
+                && (psTagSet.attr_data[1] == (byte) 0x10)
+                && (psTagSet.attr_data[2] == (byte) 0x2f)
+                && (psTagSet.attr_data[3] == (byte) 0x7d)) {
+            psTagSet.tagSet = psTagSet.attr_data[4]
+                    + (psTagSet.attr_data[5] * 256);
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Parse each of the tag definitions. */
+        /* -------------------------------------------------------------------- */
+        // psTagSet.tagList = (DGNTagDef *) CPLMalloc(sizeof(DGNTagDef) *
+        // psTagSet->tagCount);
+        nDataOffset = 48 + psTagSet.tagSetName.length + 1 + 1;
+
+        for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
+            DGNTagDef tagDef = new DGNTagDef();
+
+            // = psTagSet.tagList + iTag;
+            tagDef.id = iTag;
+
+            // CPLAssert( nDataOffset < psDGN.nElemBytes );
+			/* collect tag name. */
+            System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
+                    psDGN.abyElem.length);
+            fin[0] = 0;
+            tagDef.name = ByteUtils.bytesToString(temp, fin).toCharArray();
+            nDataOffset += ((tagDef.name.length) + 1);
+
+            /* Get tag id */
+            tagDef.id = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset])
+                    + (ByteUtils
+                    .byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
+            nDataOffset += 2;
+
+            /* Get User Prompt */
+            System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
+                    psDGN.abyElem.length);
+            fin[0] = 0;
+            tagDef.prompt = ByteUtils.bytesToString(temp, fin).toCharArray();
+            nDataOffset += ((tagDef.prompt.length) + 1);
+
+            /* Get type */
+            tagDef.type = ByteUtils
+                    .byteToUnsignedInt(psDGN.abyElem[nDataOffset])
+                    + (ByteUtils
+                    .byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
+            nDataOffset += 2;
+
+            /* skip five zeros */
+            nDataOffset += 5;
+
+            /* Get the default */
+            if (tagDef.type == 1) {
+                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
+                        psDGN.abyElem.length);
+                fin[0] = 0;
+                tagDef.defaultValue.string = ByteUtils.bytesToString(temp, fin).toCharArray();
+                nDataOffset += (tagDef.defaultValue.string.length + 1);
+            } else if ((tagDef.type == 3) || (tagDef.type == 5)) {
+                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 4);
+                fin[0] = 0;
+                tagDef.defaultValue.integer = ByteUtils.bytesToLong(temp, fin);
+
+                // memcpy( (tagDef.defaultValue.integer),psDGN.abyElem +
+                // nDataOffset, 4 );
+                tagDef.defaultValue.integer = CPL_LSBWORD32((int) tagDef.defaultValue.integer);
+                nDataOffset += 4;
+            } else if (tagDef.type == 4) {
+                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 8);
+                fin[0] = 0;
+                tagDef.defaultValue.real = ByteUtils.bytesToDouble(temp, fin);
+
+                // memcpy( (tagDef.defaultValue.real), psDGN.abyElem +
+                // nDataOffset, 8 );
+                DGNParseIEEE(tagDef.defaultValue.real);
+                nDataOffset += 8;
+            } else {
+                nDataOffset += 4;
+            }
+        }
+
+        return psTagSet;
+    }
+
+    private void DGNSetOptions(DGNInfo psDGN, int nOptions) {
+        psDGN.options = nOptions;
+    }
+
+    private void DGNSetSpatialFilter(DGNInfo psDGN, double dfXMin,
+            double dfYMin, double dfXMax, double dfYMax) {
+        if ((dfXMin == 0.0) && (dfXMax == 0.0) && (dfYMin == 0.0)
+                && (dfYMax == 0.0)) {
+            psDGN.has_spatial_filter = FALSE;
+
+            return;
+        }
+
+        psDGN.has_spatial_filter = TRUE;
+        psDGN.sf_converted_to_uor = FALSE;
+
+        psDGN.sf_min_x_geo = dfXMin;
+        psDGN.sf_min_y_geo = dfYMin;
+        psDGN.sf_max_x_geo = dfXMax;
+        psDGN.sf_max_y_geo = dfYMax;
+
+        DGNSpatialFilterToUOR(psDGN);
+    }
+
+    private String DGNDumpPoint(DGNPoint point) {
+        StringBuffer out = new StringBuffer();
+
+        out.append("(");
+        out.append(point.x).append(",");
+        out.append(point.y).append(",");
+        out.append(point.z).append(")");
+        return out.toString();
+    }
+
+    private String DGNDumpColor(byte color[]) {
+        StringBuffer out = new StringBuffer();
+
+        out.append("(");
+        out.append(color[0]).append(",");
+        out.append(color[1]).append(",");
+        out.append(color[2]).append(")");
+        return out.toString();
+    }
+
+    static class XMLTag {
+
+        private List<XMLTag> tags = null;
+
+        private String name = null;
+        private int indent;
+        private String value = null;
+        private Map<String, String> attributes = null;
+        private boolean useCDATA;
+        private String remarks = null;
+
+        XMLTag(String name, int indent) {
+            this.name = name;
+            this.indent = indent;
+        }
+
+        public XMLTag addAttribute(String name, byte value) {
+            this.addAttribute(name, Integer.toString(((int) value) & 255));
+            return this;
+        }
+
+        public XMLTag addAttribute(String name, int value) {
+            this.addAttribute(name, Integer.toString(value));
+            return this;
+        }
+
+        public XMLTag addAttribute(String name, double value) {
+            this.addAttribute(name, Double.toString(value));
+            return this;
+        }
+
+        public XMLTag addAttribute(String name, String value) {
+            if (this.attributes == null) {
+                this.attributes = new LinkedHashMap<String, String>();
+            }
+            this.attributes.put(name, value);
+            return this;
+        }
+
+        public XMLTag setValue(String value) {
+            this.value = value;
+            return this;
+        }
+
+        public XMLTag addValue(String value) {
+            if (this.value == null) {
+                this.value = value;
+            } else {
+                this.value += value;
+            }
+            return this;
+        }
+
+        public XMLTag addRemark(String remark) {
+            if (this.remarks == null) {
+                this.remarks = remark;
+            } else {
+                this.remarks += remark;
+            }
+            return this;
+        }
+
+        public XMLTag createTag(String name, int indent) {
+            return new XMLTag(name, indent);
+        }
+
+        public XMLTag addTag(XMLTag tag) {
+            if (this.tags == null) {
+                this.tags = new ArrayList<XMLTag>();
+            }
+            this.tags.add(tag);
+            return tag;
+        }
+
+        public XMLTag addPointTag(String name, double x, double y, double z) {
+            XMLTag point = this.addTag(name);
+            point.addAttribute("x", x);
+            point.addAttribute("y", y);
+            point.addAttribute("z", z);
+            return point;
+        }
+
+        public XMLTag addTag(String name, DGNPoint point) {
+            return this.addPointTag(name, point.x, point.y, point.z);
+        }
+
+        public XMLTag addTag(String name, int[] values) {
+            XMLTag tag = this.addTag(name);
+            for (int i = 0; i < values.length; i++) {
+                tag.addTag("value", values[i]);
+            }
+            return tag;
+        }
+
+        public XMLTag addTag(String name, short[] values) {
+            XMLTag tag = this.addTag(name);
+            for (int i = 0; i < values.length; i++) {
+                tag.addTag("value", values[i]);
+            }
+            return tag;
+        }
+
+        public XMLTag addTag(String name, double[] values) {
+            XMLTag tag = this.addTag(name);
+            for (int i = 0; i < values.length; i++) {
+                tag.addTag("value", values[i]);
+            }
+            return tag;
+        }
+
+        public XMLTag addTag(String name) {
+            return this.addTag(name, (String) null);
+        }
+
+        public XMLTag addTag(String name, int value) {
+            return this.addTag(name, Integer.toString(value));
+        }
+
+        public XMLTag addTag(String name, double value) {
+            return this.addTag(name, Double.toString(value));
+        }
+
+        public XMLTag addTag(String name, byte[] value) {
+            return this.addTag(name, value.toString());
+        }
+
+        public XMLTag addTag(String name, char[] value) {
+            return this.addTag(name, value.toString());
+        }
+
+        public XMLTag addTag(String name, String value) {
+            XMLTag tag = createTag(name, indent + 1);
+            if (value != null) {
+                tag.setValue(value);
+            }
+            return this.addTag(tag);
+        }
+
+        private void setUseCDATA(boolean useCDATA) {
+            this.useCDATA = useCDATA;
+        }
+
+        private String spaces(int n) {
+            String s = "                                                                                                                                                                                                                                                                                                           ";
+            return s.substring(1, n);
+        }
+
+        private String getHTMLRemarks() {
+            if (this.remarks == null) {
+                return "";
+            }
+            if (this.remarks.contains("\n")) {
+                return "<!-- \n" + this.remarks + "\n-->";
+            } else {
+                return " <!-- " + this.remarks + " -->";
+            }
+        }
+
+        public String toString() {
+            StringBuilder out = new StringBuilder();
+
+            out.append(spaces(this.indent * 4))
+                    .append("<")
+                    .append(this.name);
+            if (this.attributes != null) {
+                Iterator<Map.Entry<String, String>> it = this.attributes.entrySet().iterator();
+                while (it.hasNext()) {
+                    Map.Entry<String, String> entry = it.next();
+                    out.append(" ")
+                            .append(entry.getKey())
+                            .append("=\"")
+                            .append(entry.getValue())
+                            .append("\"");
+                }
+            }
+            if (this.tags == null && this.value == null) {
+                out.append("/>");
+                out.append(getHTMLRemarks());
+                out.append("\n");
+            } else {
+                out.append(">");
+                if (this.tags != null && !this.tags.isEmpty()) {
+                    out.append(getHTMLRemarks());
+                    out.append("\n");
+                    for (int i = 0; i < this.tags.size(); i++) {
+                        out.append(this.tags.get(i).toString());
+                    }
+                    if (this.value != null) {
+                        out.append(this.value);
+                    }
+                    out.append(spaces(this.indent * 4));
+                    out.append("</")
+                            .append(this.name)
+                            .append(">\n");
+                } else {
+                    if (this.value != null) {
+                        if (this.value.contains("\n")) {
+                            out.append("\n");
+                            out.append(this.value);
+                            out.append(spaces(this.indent * 4));
+                        } else {
+                            out.append(this.value);
+                        }
+                    }
+                    out.append("</")
+                            .append(this.name)
+                            .append(">");
+                    out.append(getHTMLRemarks());
+                    out.append("\n");
+                }
+            }
+
+            return out.toString();
+        }
+
+    }
+
+    /**
+     * Muestra por consola los elementos que contiene el DGN.
+     *
+     * @param psInfo Informaci�n del DGN.
+     * @param psElement elemento
+     */
+    public String DGNDumpElement(DGNInfo psInfo, DGNElemCore psElement) {
+        XMLTag elememtTag = new XMLTag("element", 1);
+
+        elememtTag.addAttribute("type", psElement.type);
+        elememtTag.addAttribute("typename", DGNTypeToName(psElement.type));
+        elememtTag.addAttribute("stype", psElement.stype);
+        elememtTag.addTag("dimension", psInfo.dimension);
+        elememtTag.addTag("level", psElement.level);
+        elememtTag.addTag("id", psElement.element_id);
+        elememtTag.addTag("complex", psElement.complex);
+        elememtTag.addTag("deleted", psElement.deleted);
+        elememtTag.addTag("offset", psElement.offset);
+        elememtTag.addTag("size", psElement.size);
+        elememtTag.addTag("graphic_group", psElement.graphic_group);
+        elememtTag.addTag("color", psElement.color);
+        elememtTag.addTag("weight", psElement.weight);
+        elememtTag.addTag("style", psElement.style);
+
+        XMLTag propertiesTag = elememtTag.addTag("properties");
+        propertiesTag.addAttribute("value", numberFormat("0x%08x", psElement.properties));
+        if (psElement.properties != 0) {
+            if ((psElement.properties & DGNFileHeader.DGNPF_HOLE) != 0) {
+                propertiesTag.addValue(" HOLE");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_SNAPPABLE) != 0) {
+                propertiesTag.addValue(" SNAPPABLE");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_PLANAR) != 0) {
+                propertiesTag.addValue(" PLANAR");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_ORIENTATION) != 0) {
+                propertiesTag.addValue(" ORIENTATION");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
+                propertiesTag.addValue(" ATTRIBUTES");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_MODIFIED) != 0) {
+                propertiesTag.addValue(" MODIFIED");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_NEW) != 0) {
+                propertiesTag.addValue(" NEW");
+            }
+            if ((psElement.properties & DGNFileHeader.DGNPF_LOCKED) != 0) {
+                propertiesTag.addValue(" LOCKED");
+            }
+            int nClass = psElement.properties & DGNFileHeader.DGNPF_CLASS;
+
+            if (nClass == DGNFileHeader.DGNC_PATTERN_COMPONENT) {
+                propertiesTag.addValue(" PATTERN_COMPONENT");
+            } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_ELEMENT) {
+                propertiesTag.addValue(" CONSTRUCTION_ELEMENT");
+            } else if (nClass == DGNFileHeader.DGNC_DIMENSION_ELEMENT) {
+                propertiesTag.addValue(" DIMENSION_ELEMENT");
+            } else if (nClass == DGNFileHeader.DGNC_PRIMARY_RULE_ELEMENT) {
+                propertiesTag.addValue(" PRIMARY_RULE_ELEMENT");
+            } else if (nClass == DGNFileHeader.DGNC_LINEAR_PATTERNED_ELEMENT) {
+                propertiesTag.addValue(" LINEAR_PATTERNED_ELEMENT");
+            } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_RULE_ELEMENT) {
+                propertiesTag.addValue(" CONSTRUCTION_RULE_ELEMENT");
+            }
+        }
+
+        switch (psElement.stype) {
+            case DGNFileHeader.DGNST_MULTIPOINT:
+                DGNElemMultiPoint psLine = (DGNElemMultiPoint) psElement;
+
+                XMLTag multipointTag = elememtTag.addTag("multipoint");
+                for (int i = 0; i < psLine.num_vertices; i++) {
+                    multipointTag.addTag("point", psLine.vertices[i]);
+                }
+                break;
+
+            case DGNFileHeader.DGNST_CELL_HEADER:
+                DGNElemCellHeader psCellHeader = (DGNElemCellHeader) psElement;
+
+                XMLTag headerTag = elememtTag.addTag("header");
+                headerTag.addTag("totlength", psCellHeader.totlength);
+                headerTag.addTag("name", psCellHeader.name.toString());
+                headerTag.addTag("cclass", psCellHeader.cclass);
+                headerTag.addTag("levels", psCellHeader.levels);
+                headerTag.addTag("rnglow", psCellHeader.rnglow);
+                headerTag.addTag("rnghigh", psCellHeader.rnghigh);
+                headerTag.addTag("origin", psCellHeader.origin);
+                headerTag.addTag("xscale", psCellHeader.xscale);
+                headerTag.addTag("yscale", psCellHeader.yscale);
+                headerTag.addTag("rotation", psCellHeader.rotation);
+                break;
+
+            case DGNFileHeader.DGNST_CELL_LIBRARY:
+                DGNElemCellLibrary psCellLib = (DGNElemCellLibrary) psElement;
+
+                XMLTag libraryTag = elememtTag.addTag("library");
+                libraryTag.addTag("name", psCellLib.name);
+                libraryTag.addTag("cclass", psCellLib.cclass);
+                libraryTag.addTag("levels", psCellLib.levels);
+                libraryTag.addTag("numwords", psCellLib.numwords);
+                libraryTag.addTag("dispsymb", psCellLib.dispsymb);
+                libraryTag.addTag("description", psCellLib.description);
+                break;
+
+            case DGNFileHeader.DGNST_ARC:
+                DGNElemArc psArc = (DGNElemArc) psElement;
+
+                XMLTag arcTag = elememtTag.addTag("arc");
+                if (psInfo.dimension == 2) {
+                    arcTag.addTag("origin", psArc.origin);
+                    arcTag.addTag("rotation", psArc.rotation);
+                    arcTag.addTag("quat").addRemark("not supported when dimension is 2");
+                } else {
+                    arcTag.addTag("origin", psArc.origin);
+                    arcTag.addTag("rotation").addRemark("not supported when dimension not is 2");
+                    arcTag.addTag("quat", psArc.quat);
+                }
+                arcTag.addTag("primary_axis", psArc.primary_axis);
+                arcTag.addTag("secondary_axis", psArc.secondary_axis);
+                arcTag.addTag("startang", psArc.startang);
+                arcTag.addTag("sweepang", psArc.sweepang);
+                break;
+
+            case DGNFileHeader.DGNST_TEXT:
+                DGNElemText psText = (DGNElemText) psElement;
+
+                XMLTag textTag = elememtTag.addTag("text");
+                textTag.addTag("origin", psText.origin);
+                textTag.addTag("rotation", psText.rotation);
+                textTag.addTag("font_id", psText.font_id);
+                textTag.addTag("justification", psText.justification);
+                textTag.addTag("length_mult", psText.length_mult);
+                textTag.addTag("height_mult", psText.height_mult);
+                textTag.addTag("height_raw", psText.height_raw);
+                textTag.addTag("string", psText.string);
+                break;
+
+            case DGNFileHeader.DGNST_COMPLEX_HEADER:
+                DGNElemComplexHeader psHdr = (DGNElemComplexHeader) psElement;
+                XMLTag complexHeaderTag = elememtTag.addTag("complexheader");
+
+                complexHeaderTag.addTag("totlength", psHdr.totlength);
+                complexHeaderTag.addTag("numelems", psHdr.numelems);
+                break;
+
+            case DGNFileHeader.DGNST_COLORTABLE:
+                DGNElemColorTable psCT = (DGNElemColorTable) psElement;
+                XMLTag colortableTag = elememtTag.addTag("colortable");
+
+                colortableTag.addAttribute("screen_flag", psCT.screen_flag);
+                for (int i = 0; i < 256; i++) {
+                    colortableTag.addTag("color")
+                            .addAttribute("index", i)
+                            .addAttribute("r", psCT.color_info[i][0])
+                            .addAttribute("g", psCT.color_info[i][1])
+                            .addAttribute("b", psCT.color_info[i][2]);
+                }
+                break;
+
+            case DGNFileHeader.DGNST_TCB:
+                DGNElemTCB psTCB = (DGNElemTCB) psElement;
+                XMLTag tcbTag = elememtTag.addTag("TCB");
+
+                tcbTag.addTag("dimension", psTCB.dimension);
+                tcbTag.addTag("uor_per_subunit", psTCB.uor_per_subunit);
+                tcbTag.addTag("subunits_per_master", psTCB.subunits_per_master);
+                tcbTag.addPointTag("origin", psTCB.origin_x, psTCB.origin_y, psTCB.origin_z);
+
+                for (int iView = 0; iView < 8; iView++) {
+                    DGNViewInfo psView = psTCB.views[iView];
+                    XMLTag viewTag = tcbTag.addTag("view");
+
+                    viewTag.addAttribute("index", iView);
+
+                    viewTag.addTag("flags", numberFormat("0x%08x", psView.flags));
+                    viewTag.addTag("levels", psView.levels);
+                    viewTag.addTag("origin", psView.origin);
+                    viewTag.addTag("transmatrx", psView.transmatrx);
+                    viewTag.addTag("levels", psView.levels);
+                }
+                break;
+
+            case DGNFileHeader.DGNST_TAG_SET:
+                DGNElemTagSet psTagSet = (DGNElemTagSet) psElement;
+                XMLTag setTag = elememtTag.addTag("tagset");
+
+                setTag.addTag("tagSetName", psTagSet.tagSetName);
+                setTag.addTag("tagSet", psTagSet.tagSet);
+                setTag.addTag("flags", "0x" + Integer.toHexString(psTagSet.flags));
+                setTag.addTag("tagCount", psTagSet.tagCount);
+
+                for (int iTag = 0; iTag < psTagSet.tagCount; iTag++) {
+                    DGNTagDef psTagDef = psTagSet.tagList[iTag];
+                    XMLTag tagTag = setTag.addTag("tag");
+
+                    tagTag.addAttribute("index", iTag);
+                    tagTag.addTag("name", psTagDef.name);
+                    tagTag.addTag("type", psTagDef.type);
+                    tagTag.addTag("prompt", psTagDef.prompt);
+                    tagTag.addTag("default_string", psTagDef.defaultValue.string);
+                    tagTag.addTag("default_integer", psTagDef.defaultValue.integer);
+                    tagTag.addTag("default_real", psTagDef.defaultValue.real);
+                }
+                break;
+
+            case DGNFileHeader.DGNST_TAG_VALUE:
+                DGNElemTagValue psTag = (DGNElemTagValue) psElement;
+
+                XMLTag tagvalueTag = elememtTag.addTag("tagvalue");
+
+                tagvalueTag.addTag("tagType", psTag.tagType);
+                tagvalueTag.addTag("tagSet", psTag.tagSet);
+                tagvalueTag.addTag("tagIndex", psTag.tagIndex);
+                tagvalueTag.addTag("tagLength", psTag.tagLength);
+                tagvalueTag.addTag("value_string", psTag.tagValue.string);
+                tagvalueTag.addTag("value_integer", psTag.tagValue.integer);
+                tagvalueTag.addTag("value_real", psTag.tagValue.real);
+                break;
+
+            case DGNFileHeader.DGNST_GROUP_DATA:
+                break;
+
+            default:
+                break;
+        }
+
+        if (psElement.attr_bytes > 0) {
+            int iLink;
+
+            elememtTag.addTag("attr_bytes", psElement.attr_bytes);
+
+            Iterator it = this.linksiterator(psElement);
+            while (it.hasNext()) {
+                DGNLink dgnlink = (DGNLink) it.next();
+                if (dgnlink == null) {
+                    break;
+                }
+                XMLTag linkTag = elememtTag.addTag("link");
+
+                linkTag.addAttribute("index", dgnlink.index);
+                linkTag.addAttribute("entitynum", dgnlink.entityNum);
+                linkTag.addAttribute("mslink", dgnlink.msLink);
+                linkTag.setValue(dumpBuffer(dgnlink.data));
+                linkTag.setUseCDATA(true);
+            }
+        }
+        return elememtTag.toString();
+    }
+
+    public DGNLink DGNGetLinkage(DGNElemCore psElement, Integer index,
+            Integer type, Integer entityCode, Integer mslink, Pattern data) {
+        Iterator it = this.linksiterator(psElement);
+        while (it.hasNext()) {
+            DGNLink link = (DGNLink) it.next();
+            if( index != null && index.intValue()!=link.getIndex() ) {
+                continue;
+            }
+            if( type != null && type.intValue()!=link.getType()) {
+                continue;
+            }
+            if( entityCode != null && entityCode.intValue()!=link.getEntityCode()) {
+                continue;
+            }
+            if( mslink != null && mslink.intValue()!=link.getMSLink()) {
+                continue;
+            }
+            if( data!=null && !data.matcher(link.getDataAsHexadecimal()).matches() ) {
+                continue;
+            } 
+            return link;
+        }
+        return null;
+    }
+
+    private class LinksIterator implements Iterator {
+
+        private DGNElemCore psElement;
+        private int link;
+        private DGNLink nextLink;
+
+        LinksIterator(DGNElemCore psElement) {
+            this.psElement = psElement;
+            this.link = 0;
+            this.nextLink = null;
+        }
+
+        public boolean hasNext() {
+            this.nextLink = DGNGetLinkage(getInfo(), psElement, this.link);
+            return this.nextLink != null;
+        }
+
+        public Object next() {
+            DGNLink x = this.nextLink;
+            if (x != null) {
+                this.link++;
+            }
+            return x;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    public Iterator linksiterator(DGNElemCore psElement) {
+        return new LinksIterator(psElement);
+    }
+    
+    public int DGNGetLinkageCount(DGNElemCore psElement) {
+        int count = 0;
+        Iterator it = linksiterator(psElement);
+        while( it.hasNext() ) {
+            it.next();
+            count++;
+        }
+        return count;
+    }
+    
+    /**
+     * Returns requested linkage raw data. A pointer to the raw data for the
+     * requested attribute linkage is returned as well as (potentially) various
+     * information about the linkage including the linkage type, database entity
+     * number and MSLink value, and the length of the raw linkage data in bytes.
+     * If the requested linkage (iIndex) does not exist a value of zero is
+     * returned. The entity number is (loosely speaking) the index of the table
+     * within the current database to which the MSLINK value will refer. The
+     * entity number should be used to lookup the table name in the MSCATALOG
+     * table. The MSLINK value is the key value for the record in the target
+     * table.
+     *
+     * @param psDGN the file from which the element originated.
+     * @param psElement the element to report on.
+     * @param iIndex the zero based index of the linkage to fetch.
+     */
+    private DGNLink DGNGetLinkage(DGNInfo psDGN, DGNElemCore psElement, int iIndex) {
+
+        int nAttrOffset;
+        int iLinkage = 0;
+        int nLinkSize;
+        try {
+            for (iLinkage = 0, nAttrOffset = 0; (nLinkSize = DGNGetAttrLinkSize(
+                    psDGN, psElement, nAttrOffset)) != 0; iLinkage++, nAttrOffset += nLinkSize) {
+                if (iLinkage == iIndex) {
+                    int nLinkageType = 0;
+                    int nEntityNum = 0;
+                    int nMSLink = 0;
+
+                    if ((psElement.attr_data[nAttrOffset + 0] == (byte) 0x00)
+                            && ((psElement.attr_data[nAttrOffset + 1] == (byte) 0x00)
+                            || (psElement.attr_data[nAttrOffset + 1] == (byte) 0x80))) {
+                        nLinkageType = DGNFileHeader.DGNLT_DMRS;
+                        nEntityNum = psElement.attr_data[nAttrOffset + 2]
+                                + (psElement.attr_data[nAttrOffset + 3] * 256);
+                        nMSLink = psElement.attr_data[nAttrOffset + 4]
+                                + (psElement.attr_data[nAttrOffset + 5] * 256)
+                                + (psElement.attr_data[nAttrOffset + 6] * 65536);
+                    } else {
+                        nLinkageType = psElement.attr_data[nAttrOffset + 2]
+                                + (psElement.attr_data[nAttrOffset + 3] * 256);
+                    }
+
+                    // Possibly an external database linkage?
+                    if ((nLinkSize == 16)
+                            && (nLinkageType != DGNFileHeader.DGNLT_SHAPE_FILL)) {
+                        nEntityNum = psElement.attr_data[nAttrOffset + 6]
+                                + (psElement.attr_data[nAttrOffset + 7] * 256);
+                        nMSLink = psElement.attr_data[nAttrOffset + 8]
+                                + (psElement.attr_data[nAttrOffset + 9] * 256)
+                                + (psElement.attr_data[nAttrOffset + 10] * 65536)
+                                + (psElement.attr_data[nAttrOffset + 11] * 65536 * 256);
+                    }
+
+                    DGNLink dgnlink = new DGNLink();
+
+                    dgnlink.type = nLinkageType;
+                    dgnlink.entityNum = nEntityNum;
+                    dgnlink.msLink = nMSLink;
+                    dgnlink.length = nLinkSize;
+
+                    byte[] temp = new byte[psElement.attr_data.length - nAttrOffset];
+                    System.arraycopy(psElement.attr_data, nAttrOffset, temp, 0,
+                            psElement.attr_data.length - nAttrOffset);
+
+                    dgnlink.type = nLinkageType;
+                    dgnlink.entityNum = nEntityNum;
+                    dgnlink.msLink = nMSLink;
+                    dgnlink.length = nLinkSize;
+                    dgnlink.data = temp;
+
+                    return dgnlink;
+                }
+            }
+        } catch (Exception ex) {
+            logwarn("Can't get an external database linkage (iLinkage=" + iLinkage + ").", ex);
+        }
+        return null;
+    }
+
+    /**
+     * Devuelve el tama�o de los atributos de un elemento.
+     *
+     * @param psDGN Informaci�n del DGN.
+     * @param psElement elemento.
+     * @param nOffset indice donde se encuentra el elemento.
+     *
+     * @return Entero que representa el Tama�o.
+     */
+    private int DGNGetAttrLinkSize(DGNInfo psDGN, DGNElemCore psElement,
+            int nOffset) {
+        if (psElement.attr_bytes < (nOffset + 4)) {
+            return 0;
+        }
+
+        /* DMRS Linkage */
+        if (((psElement.attr_data[nOffset + 0] == 0) && (psElement.attr_data[nOffset + 1] == 0))
+                || ((psElement.attr_data[nOffset + 0] == 0) && (psElement.attr_data[nOffset + 1] == (byte) 0x80))) {
+            return 8;
+        }
+
+        /* If low order bit of second byte is set, first byte is length */
+        if ((psElement.attr_data[nOffset + 1] & (byte) 0x10) != FALSE) {
+            return (psElement.attr_data[nOffset + 0] * 2) + 2;
+        }
+
+        /* unknown */
+        return 0;
+    }
+
+    /**
+     * A partir de un entero devuelve el un String con el tipo del elemento.
+     *
+     * @param nType tipo.
+     *
+     * @return String con el nombre del elemento.
+     */
+    String DGNTypeToName(int nType) {
+        // char[] szNumericResult=new char[16];
+        switch (nType) {
+            case DGNFileHeader.DGNT_CELL_LIBRARY:
+                return DGNFileHeader.DGNT_CELL_LIBRARY_NAME;
+
+            case DGNFileHeader.DGNT_CELL_HEADER:
+                return DGNFileHeader.DGNT_CELL_HEADER_NAME;
+
+            case DGNFileHeader.DGNT_LINE:
+                return DGNFileHeader.DGNT_LINE_NAME;
+
+            case DGNFileHeader.DGNT_LINE_STRING:
+                return DGNFileHeader.DGNT_LINE_STRING_NAME;
+
+            case DGNFileHeader.DGNT_GROUP_DATA:
+                return DGNFileHeader.DGNT_GROUP_DATA_NAME;
+
+            case DGNFileHeader.DGNT_SHAPE:
+                return DGNFileHeader.DGNT_SHAPE_NAME;
+
+            case DGNFileHeader.DGNT_TEXT_NODE:
+                return DGNFileHeader.DGNT_TEXT_NODE_NAME;
+
+            case DGNFileHeader.DGNT_DIGITIZER_SETUP:
+                return DGNFileHeader.DGNT_DIGITIZER_SETUP_NAME;
+
+            case DGNFileHeader.DGNT_TCB:
+                return DGNFileHeader.DGNT_TCB_NAME;
+
+            case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
+                return DGNFileHeader.DGNT_LEVEL_SYMBOLOGY_NAME;
+
+            case DGNFileHeader.DGNT_CURVE:
+                return DGNFileHeader.DGNT_CURVE_NAME;
+
+            case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
+                return DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER_NAME;
+
+            case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
+                return DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER_NAME;
+
+            case DGNFileHeader.DGNT_ELLIPSE:
+                return DGNFileHeader.DGNT_ELLIPSE_NAME;
+
+            case DGNFileHeader.DGNT_ARC:
+                return DGNFileHeader.DGNT_ARC_NAME;
+
+            case DGNFileHeader.DGNT_TEXT:
+                return DGNFileHeader.DGNT_TEXT_NAME;
+
+            case DGNFileHeader.DGNT_BSPLINE:
+                return DGNFileHeader.DGNT_BSPLINE_NAME;
+
+            case DGNFileHeader.DGNT_APPLICATION_ELEM:
+                return DGNFileHeader.DGNT_APPLICATION_ELEM_NAME;
+
+            case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
+                return DGNFileHeader.DGNT_SHARED_CELL_DEFN_NAME;
+
+            case DGNFileHeader.DGNT_SHARED_CELL_ELEM:
+                return DGNFileHeader.DGNT_SHARED_CELL_ELEM_NAME;
+
+            case DGNFileHeader.DGNT_TAG_VALUE:
+                return DGNFileHeader.DGNT_TAG_VALUE_NAME;
+
+            default:
+                logwarn("Can't get element type name for value '" + nType + "'.", null);
+                return DGNFileHeader.DGNT_UNKNOWN_NAME;
+        }
+    }
+
+    /**
+     * Muestra por consola la fila de un elemento.
+     *
+     * @param psDGN informaci�n del DGN.
+     * @param psCore elemento
+     * @param fpOut path del fichero DGN.
+     */
+    private void DGNDumpRawElement(DGNInfo psDGN, DGNElemCore psCore,
+            String fpOut) {
+        int i;
+        int iChar = 0;
+        byte[] szLine = new byte[80];
+
+        for (i = 0; i < psCore.raw_bytes; i++) {
+            byte[] szHex = new byte[3];
+
+            if ((i % 16) == 0) {
+                int[] f = new int[1];
+                byte[] temp = new byte[4];
+                f[0] = 0;
+                ByteUtils.intToBytes(i, temp, f);
+                System.arraycopy(temp, 0, szLine, 0, 4);
+                iChar = 0;
+            }
+
+            szHex[0] = psCore.raw_data[i];
+            szHex[1] = (byte) 0x00;
+
+            System.arraycopy(szHex, 0, szLine, 8 + (iChar * 2), 2);
+
+            if ((psCore.raw_data[i] < 32) || (psCore.raw_data[i] > 127)) {
+                szLine[42 + iChar] = '.';
+            } else {
+                szLine[42 + iChar] = psCore.raw_data[i];
+            }
+
+            if ((i == (psCore.raw_bytes - 1)) || (((i + 1) % 16) == 0)) {
+                int[] f = new int[1];
+                f[0] = 0;
+
+                byte[] temp = new byte[1];
+                byte[] temp1 = new byte[16];
+                int k = 0;
+
+                for (int j = 1; j < 32; j = j + 2) {
+                    System.arraycopy(szLine, j + 7, temp, 0, 1);
+                    temp1[k] = temp[0];
+                    k++;
+                }
+                f[0] = 42;
+
+                char[] tempchar = new char[16];
+
+                for (int j = 0; j < 16; j++) {
+                    tempchar[j] = (char) szLine[42 + j];
+                }
+            }
+
+            iChar++;
+        }
+    }
+
+    /**
+     * Devuelve el extent del elemento.
+     *
+     * @param psDGN Informaci�n del DGN.
+     * @param padfExtents doubles que representan el rect�ngulo del extent.
+     *
+     * @return Entero que muestra si se ha calculado correctamente.
+     */
+    private int DGNGetExtents(DGNInfo psDGN, double[] padfExtents) {
+        // DGNInfo *psDGN = (DGNInfo *) hDGN;
+        DGNPoint sMin = new DGNPoint();
+        DGNPoint sMax = new DGNPoint();
+
+        DGNBuildIndex(psDGN);
+
+        if (psDGN.got_bounds == FALSE) {
+            return FALSE;
+        }
+
+        double minX = psDGN.min_x;
+        double minY = psDGN.min_y;
+        double minZ = psDGN.min_z;
+        logdebug("psDGN.min: x= " + minX + ", y= " + minY + ", z= " + minZ);
+
+        if (minX < 0) {
+            minX = minX + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        if (minY < 0) {
+            minY = minY + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        if (minZ < 0) {
+            minZ = minZ + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        logdebug("psDGN.min fixed: x= " + minX + ", y= " + minY + ", z= " + minZ);
+
+        sMin.x = minX - 2147483648.0;
+        sMin.y = minY - 2147483648.0;
+        sMin.z = minZ - 2147483648.0;
+
+        DGNTransformPoint(psDGN, sMin);
+
+        padfExtents[0] = sMin.x;
+        padfExtents[1] = sMin.y;
+        padfExtents[2] = sMin.z;
+
+        double maxX = psDGN.max_x;
+        double maxY = psDGN.max_y;
+        double maxZ = psDGN.max_z;
+
+        logdebug("psDGN.max: x= " + maxX + ", y= " + maxY + ", z= " + maxZ);
+        if (maxX < 0) {
+            maxX = maxX + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        if (maxY < 0) {
+            maxY = maxY + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        if (maxZ < 0) {
+            maxZ = maxZ + (2 * ((long) Integer.MAX_VALUE + 1));
+        }
+        logdebug("psDGN.max fixed: x= " + maxX + ", y= " + maxY + ", z= " + maxZ);
+
+        sMax.x = maxX - 2147483648.0;
+        sMax.y = maxY - 2147483648.0;
+        sMax.z = maxZ - 2147483648.0;
+
+        DGNTransformPoint(psDGN, sMax);
+
+        padfExtents[3] = sMax.x;
+        padfExtents[4] = sMax.y;
+        padfExtents[5] = sMax.z;
+
+        return TRUE;
+    }
+
+    /**
+     * Construye un �ndice al DGN.
+     *
+     * @param psDGN Informaci�n del DGN.
+     */
+    private void DGNBuildIndex(DGNInfo psDGN) {
+        DGNElemCore elemento = new DGNElemCore(this);
+        int nMaxElements;
+        int nType;
+        int nLevel;
+        long nLastOffset;
+
+        if (psDGN.index_built != FALSE) {
+            return;
+        }
+
+        psDGN.index_built = TRUE;
+
+        // DGNRewind( psDGN );
+        nMaxElements = 0;
+
+        // nLastOffset = VSIFTell( psDGN.fp );
+        nLastOffset = bb.position(); // psDGN.ftall;
+
+        while (DGNLoadRawElement(psDGN, elemento) != FALSE) {
+            DGNElementInfo psEI; // = new DGNElementInfo();
+
+            if (psDGN.element_count == nMaxElements) {
+                int oldMax = nMaxElements;
+                nMaxElements = (int) (nMaxElements * 1.5) + 500;
+
+                DGNElementInfo[] nuevo = new DGNElementInfo[nMaxElements];
+
+                for (int i = 0; i < oldMax; i++) {
+                    nuevo[i] = psDGN.element_index[i];
+                }
+
+                psDGN.element_index = nuevo;
+
+                // psDGN.element_index = (DGNElementInfo *) CPLRealloc(
+                // psDGN.element_index,
+                // nMaxElements * sizeof(DGNElementInfo) );
+            }
+
+            psDGN.element_index[psDGN.element_count] = new DGNElementInfo();
+            psEI = psDGN.element_index[psDGN.element_count];
+            psEI.level = elemento.level;
+            psEI.type = elemento.type;
+            psEI.flags = 0;
+            psEI.offset = nLastOffset;
+
+            if ((psDGN.abyElem[0] * (byte) 0x80) == (byte) 0x80) {
+                psEI.flags |= DGNFileHeader.DGNEIF_COMPLEX;
+            }
+
+            if ((psDGN.abyElem[1] * (byte) 0x80) == (byte) 0x80) {
+                psEI.flags |= DGNFileHeader.DGNEIF_DELETED;
+            }
+
+            if ((elemento.type == DGNFileHeader.DGNT_LINE)
+                    || (elemento.type == DGNFileHeader.DGNT_LINE_STRING)
+                    || (elemento.type == DGNFileHeader.DGNT_SHAPE)
+                    || (elemento.type == DGNFileHeader.DGNT_CURVE)
+                    || (elemento.type == DGNFileHeader.DGNT_BSPLINE)) {
+                psEI.stype = DGNFileHeader.DGNST_MULTIPOINT;
+            } else if ((elemento.type == DGNFileHeader.DGNT_GROUP_DATA)
+                    && (elemento.level == DGNFileHeader.DGN_GDL_COLOR_TABLE)) {
+                DGNElemCore psCT = DGNParseColorTable(psDGN);
+
+                logdebug("TABLA DE COLORES!!");
+                psEI.stype = DGNFileHeader.DGNST_COLORTABLE;
+                m_colorTable = (DGNElemColorTable) psCT;
+
+            } else if ((elemento.type == DGNFileHeader.DGNT_ELLIPSE)
+                    || (elemento.type == DGNFileHeader.DGNT_ARC)) {
+                psEI.stype = DGNFileHeader.DGNST_ARC;
+            } else if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)
+                    || (elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)) {
+                psEI.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
+            } else if (elemento.type == DGNFileHeader.DGNT_TEXT) {
+                psEI.stype = DGNFileHeader.DGNST_TEXT;
+            } else if (elemento.type == DGNFileHeader.DGNT_TAG_VALUE) {
+                psEI.stype = DGNFileHeader.DGNST_TAG_VALUE;
+            } else if (elemento.type == DGNFileHeader.DGNT_APPLICATION_ELEM) {
+                if (elemento.level == 24) {
+                    psEI.stype = DGNFileHeader.DGNST_TAG_SET;
+                } else {
+                    psEI.stype = DGNFileHeader.DGNST_CORE;
+                }
+            } else if (elemento.type == DGNFileHeader.DGNT_TCB) {
+                DGNElemCore psTCB = DGNParseTCB(psDGN);
+
+                // DGNFreeElement( psDGN, psTCB );
+                psEI.stype = DGNFileHeader.DGNST_TCB;
+            } else {
+                psEI.stype = DGNFileHeader.DGNST_CORE;
+            }
+
+            // DGNInfo tempo = new DGNInfo();
+            double[] anRegion;
+
+            if (((psEI.flags & DGNFileHeader.DGNEIF_DELETED) == FALSE)
+                    & ((psEI.flags & DGNFileHeader.DGNEIF_COMPLEX) == FALSE)
+                    & ((anRegion = DGNGetRawExtents(psDGN, null, elemento)) != null)) {
+                if (psDGN.got_bounds != FALSE) {
+                    psDGN.min_x = Math.min(psDGN.min_x, anRegion[0]);
+                    psDGN.min_y = Math.min(psDGN.min_y, anRegion[1]);
+                    psDGN.min_z = Math.min(psDGN.min_z, anRegion[2]);
+                    psDGN.max_x = Math.max(psDGN.max_x, anRegion[3]);
+                    psDGN.max_y = Math.max(psDGN.max_y, anRegion[4]);
+                    psDGN.max_z = Math.max(psDGN.max_z, anRegion[5]);
+                } else {
+                    psDGN.min_x = anRegion[0];
+                    psDGN.min_y = anRegion[1];
+                    psDGN.min_z = anRegion[2];
+                    psDGN.max_x = anRegion[3];
+                    psDGN.max_y = anRegion[4];
+                    psDGN.max_z = anRegion[5];
+                    psDGN.got_bounds = TRUE;
+                }
+            }
+
+            psDGN.element_count++;
+
+            nLastOffset = bb.position();;
+        }
+        psDGN.max_element_count = nMaxElements;
+    }
+
+    /**
+     * Devuelve el rect�ngulo que representa el extent del elemento.
+     *
+     * @param psDGN informaci�n del DGN.
+     * @param psElement elemento.
+     * @param psMin punto m�nimo.
+     * @param psMax punto m�ximo.
+     *
+     * @return Entero para comprobar si se ha calculado correctamente.
+     */
+    private int DGNGetElementExtents(DGNInfo psDGN, DGNElemCore psElement,
+            DGNPoint psMin, DGNPoint psMax) {
+        // DGNInfo *psDGN = (DGNInfo *) hDGN;
+        long[] anMin = new long[3];
+        long[] anMax = new long[3];
+        DGNInfo tempo = new DGNInfo();
+        double[] bResult;
+
+        /* -------------------------------------------------------------------- */
+        /* Get the extents if we have raw data in the element, or */
+        /* loaded in the file buffer. */
+        /* -------------------------------------------------------------------- */
+        if (psElement.raw_data != null) {
+            bResult = DGNGetRawExtents(psDGN, psElement.raw_data, psElement);
+        } else {
+            if (psElement.element_id == (psDGN.next_element_id - 1)) {
+                bResult = DGNGetRawExtents(psDGN, psDGN.abyElem, psElement);
+            } else {
+                return FALSE;
+            }
+        }
+
+        if (bResult == null) {
+            return FALSE;
+        }
+
+        /* -------------------------------------------------------------------- */
+        /* Transform to user coordinate system and return. The offset */
+        /* is to convert from "binary offset" form to twos complement. */
+        /* -------------------------------------------------------------------- */
+        // TODO: revisar por que le resta se valor a capon
+        psMin.x = tempo.min_x - 2147483648.0;
+        psMin.y = tempo.min_y - 2147483648.0;
+        psMin.z = tempo.min_z - 2147483648.0;
+
+        psMax.x = tempo.max_x - 2147483648.0;
+        psMax.y = tempo.max_y - 2147483648.0;
+        psMax.z = tempo.max_z - 2147483648.0;
+
+        DGNTransformPoint(psDGN, psMin);
+        DGNTransformPoint(psDGN, psMax);
+
+        return TRUE;
+    }
+
+    /**
+     * Devuelve los �ndices de los elementos del DGN.
+     *
+     * @param psDGN Informaci�n del DGN.
+     * @param pnElementCount N�mero de elementos.
+     *
+     * @return �ndices.
+     */
+    private DGNElementInfo[] DGNGetElementIndex(DGNInfo psDGN,
+            int[] pnElementCount) {
+        // DGNInfo *psDGN = (DGNInfo *) hDGN;
+        DGNBuildIndex(psDGN);
+
+        if (pnElementCount[0] != -1) {
+            pnElementCount[0] = psDGN.element_count;
+        }
+
+        return psDGN.element_index;
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGNLookupColor() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Translate color index into RGB values. If no color table has yet been
+     * encountered in the file a hard-coded "default" color table will be used.
+     * This seems to be what Microstation uses as a color table when there isn't
+     * one in a DGN file but I am not absolutely convinced it is appropriate.
+     *
+     * @param color_index the color index to lookup.
+     *
+     * @return TRUE on success or FALSE on failure. May fail if color_index is
+     * out of range.
+     */
+    public Color DGNLookupColor(int color_index) {
+        int r;
+        int g;
+        int b;
+
+        if ((color_index < 0) || (color_index > 255)) {
+            return null;
+        }
+
+        if (info.got_color_table == 0) {
+            r = abyDefaultPCT[color_index][0];
+            g = abyDefaultPCT[color_index][1];
+            b = abyDefaultPCT[color_index][2];
+        } else {
+            r = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][0]);
+            g = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][1]);
+            b = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][2]);
+        }
+        if ((r == 255) && (g == 255) && (b == 255)) {
+            r = g = b = 0; // El color blanco lo devolvemos como negro.
+        }
+
+        return new Color(r, g, b);
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGNGetShapeFillInfo() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Fetch fill color for a shape. This method will check for a 0x0041 user
+     * attribute linkaged with fill color information for the element. If found
+     * the function returns TRUE, and places the fill color in pnColor,
+     * otherwise FALSE is returned and pnColor is not updated.
+     *
+     * @param psElem the element.
+     *
+     * @return index of color on success or -1 on failure.
+     */
+    public int DGNGetShapeFillInfo(DGNElemCore psElem) {
+        int iLink;
+        int color_index = -1;
+
+        for (iLink = 0; true; iLink++) {
+            DGNLink dgnlink = DGNGetLinkage(info, psElem, iLink);
+
+            if (dgnlink == null) {
+                return -1;
+            }
+            if ((dgnlink.type == DGNFileHeader.DGNLT_SHAPE_FILL)
+                    && (dgnlink.length >= 7)) {
+                color_index = ByteUtils.getUnsigned(dgnlink.data[8]);
+                break;
+            }
+        }
+
+        return color_index;
+    }
+
+    /**
+     * *********************************************************************
+     */
+    /* DGNGetAssocID() */
+    /**
+     * *********************************************************************
+     */
+    /**
+     * Fetch association id for an element. This method will check if an element
+     * has an association id, and if so returns it, otherwise returning -1.
+     * Association ids are kept as a user attribute linkage where present.
+     *
+     * @param psElem the element.
+     *
+     * @return The id or -1 on failure.
+     */
+    int DGNGetAssocID(DGNElemCore psElem) {
+        int iLink;
+
+        for (iLink = 0; true; iLink++) {
+            DGNLink dgnlink = DGNGetLinkage(info, psElem, iLink);
+            if (dgnlink == null) {
+                return -1;
+            }
+            if ((dgnlink.type == DGNFileHeader.DGNLT_ASSOC_ID)
+                    && (dgnlink.length >= 8)) {
+                byte[] pabyData = dgnlink.data;
+                return ByteUtils.getUnsigned(pabyData[4])
+                        + (ByteUtils.getUnsigned(pabyData[5]) * 256)
+                        + (ByteUtils.getUnsigned(pabyData[6]) * 256 * 256)
+                        + (ByteUtils.getUnsigned(pabyData[7]) * 256 * 256 * 256);
+            }
+        }
+    }
+
+    private void logwarn(String msg, Throwable cause) {
+        if (logErrors) {
+            if (cause == null) {
+                logger.warn(msg);
+            } else {
+                logger.warn(msg, cause);
+            }
+        }
+    }
+
+    private void loginfo(String msg, Throwable cause) {
+        if (logErrors) {
+            logger.info(msg);
+        }
+    }
+
+    private void logdebug(String msg) {
+        if (logErrors) {
+            logger.debug(msg);
+        }
+    }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElementInfo.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElementInfo.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElementInfo.java	(revision 509)
@@ -0,0 +1,66 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo Info.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElementInfo {
+	public int level; /*!< Element Level: 0-63 */
+	public int type; /*!< Element type (DGNT_*) */
+	public int stype; /*!< Structure type (DGNST_*) */
+	public int flags; /*!< Other flags */
+	public long offset; /*!< Offset within file (private) */
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemMultiPoint.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemMultiPoint.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemMultiPoint.java	(revision 509)
@@ -0,0 +1,100 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo MultiPoint.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemMultiPoint extends DGNElemCore {
+	public int num_vertices; /*!< Number of vertices in "vertices" */
+	public DGNPoint[] vertices;
+        
+        public DGNElemMultiPoint(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+        
+        public boolean isPoint() {
+            if( this.num_vertices == 2 && (
+                this.vertices[0].x == this.vertices[1].x  &&
+                this.vertices[0].y == this.vertices[1].y) ) {
+                return true;
+            }
+            return false;
+        }
+        
+        public boolean isPolygon() {
+
+            if( this.num_vertices > 2 &&
+                (this.vertices[0].x == this.vertices[this.num_vertices - 1].x) &&
+                (this.vertices[0].y == this.vertices[this.num_vertices - 1].y)) {
+                return true;
+            }
+            return false;
+        }
+        
+        public DGNPoint getPoint(int pos) {
+            return this.vertices[pos];
+        }
+        
+        public int getNumVertices() {
+            return this.num_vertices;
+        }
+        
+        public DGNPoint getVertex(int n) {
+            return this.vertices[n];
+        }
+
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellLibrary.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellLibrary.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemCellLibrary.java	(revision 509)
@@ -0,0 +1,42 @@
+
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo CellLibrary.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemCellLibrary extends DGNElemCore {
+
+	public int celltype; /*!< Cell type. */
+	public int attindx; /*!< Attribute linkage. */
+	public byte[] name = new byte[7]; //7           /*!< Cell name */
+	public int numwords; /*!< Number of words in cell definition */
+	public int dispsymb; /*!< Display symbol */
+	public int cclass; /*!< Class bitmap */
+	public int[] levels = new int[4]; //4         /*!< Levels used in cell */
+	public byte[] description = new byte[28]; //28   /*!< Description */
+        
+        public DGNElemCellLibrary(DGNReader dgnreader) {
+            super(dgnreader);
+        }        
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemArc.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemArc.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemArc.java	(revision 509)
@@ -0,0 +1,88 @@
+
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo Arc.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemArc extends DGNElemCore {
+
+	public DGNPoint origin = new DGNPoint(); /*!< Origin of ellipse */
+	public double primary_axis;
+
+	//=new double[4];	/*!< Primary axis length */
+	public double secondary_axis;
+
+	//=new double[4]; /*!< Secondary axis length */
+	public double rotation; /*!< Counterclockwise rotation in degrees */
+	public double[] quat = new double[4]; //4
+	public double startang;
+
+	/*!< Start angle (degrees counterclockwise of primary axis) */
+	public double sweepang; /*!< Sweep angle (degrees) */
+        
+        public DGNElemArc(DGNReader dgnreader) {
+            super(dgnreader);
+        }        
+        
+        public boolean isSurface() {
+            return this.isEllipse();
+        }
+        
+        public boolean isEllipticArc() {
+            return this.primary_axis != this.secondary_axis;
+        }
+        
+        public boolean isArc() {
+            return this.primary_axis == this.secondary_axis;
+        }
+        
+        public DGNPoint getCenter() {
+            return this.origin;
+        }
+        
+        public double getRotation() {
+            return this.rotation;
+        }
+        
+        public double getStartAngle() {
+            return this.startang;
+        }
+        
+        public double getSweepAngle() {
+            return this.sweepang;
+        }
+        
+        public double getRadious() {
+            return this.primary_axis;
+        }
+        
+        public double getPrimaryAxis() {
+            return this.primary_axis;
+        }
+        
+        public double getSecodaryAxis() {
+            return this.secondary_axis;
+        }
+        
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagValue.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagValue.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTagValue.java	(revision 509)
@@ -0,0 +1,72 @@
+/*
+ * Created on 21-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo TagValue.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemTagValue extends DGNElemCore {
+	public int tagType; /*!< Tag type indicator, DGNTT_* */
+	public int tagSet; /*!< Which tag set does this relate to? */
+	public int tagIndex; /*!< Tag index within tag set. */
+	public int tagLength; /*!< Length of tag information (text) */
+	public tagValueUnion tagValue = new tagValueUnion();
+        
+        
+        public DGNElemTagValue(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTCB.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTCB.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNElemTCB.java	(revision 509)
@@ -0,0 +1,79 @@
+/*
+ * Created on 17-jul-2003
+ *
+ * Copyright (c) 2003
+ * Francisco José Peñarrubia Martínez
+ * IVER Tecnologías de la Información S.A.
+ * Salamanca 50
+ * 46005 Valencia (        SPAIN )
+ * +34 963163400
+ * mailto:fran@iver.es
+ * http://www.iver.es
+ */
+/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
+ *
+ * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
+ *
+ * For more information, contact:
+ *
+ *  Generalitat Valenciana
+ *   Conselleria d'Infraestructures i Transport
+ *   Av. Blasco Ib��ez, 50
+ *   46010 VALENCIA
+ *   SPAIN
+ *
+ *      +34 963862235
+ *   gvsig@gva.es
+ *      www.gvsig.gva.es
+ *
+ *    or
+ *
+ *   IVER T.I. S.A
+ *   Salamanca 50
+ *   46005 Valencia
+ *   Spain
+ *
+ *   +34 963163400
+ *   dac@iver.es
+ */
+package org.gvsig.fmap.dal.store.dgn.lib;
+
+/**
+ * Clase utilizada para guardar un elemento de tipo TCB.
+ *
+ * @author Vicente Caballero Navarro
+ */
+public class DGNElemTCB extends DGNElemCore {
+
+	public int dimension; /*!< Dimension (2 or 3) */
+	public double origin_x; /*!< X origin of UOR space in master units(?)*/
+	public double origin_y; /*!< Y origin of UOR space in master units(?)*/
+	public double origin_z; /*!< Z origin of UOR space in master units(?)*/
+	public double uor_per_subunit; /*!< UOR per subunit. */
+	public char[] sub_units = new char[3];
+
+	//3      /*!< User name for subunits (2 chars)*/
+	public double subunits_per_master; /*!< Subunits per master unit. */
+	public char[] master_units = new char[3];
+
+	//3   /*!< User name for master units (2 chars)*/
+	public DGNViewInfo[] views = new DGNViewInfo[8]; //8
+        
+        public DGNElemTCB(DGNReader dgnreader) {
+            super(dgnreader);
+        }
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProviderFactory.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProviderFactory.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNStoreProviderFactory.java	(revision 509)
@@ -0,0 +1,57 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.util.List;
+
+import org.gvsig.fmap.dal.DataParameters;
+import org.gvsig.fmap.dal.DataStoreProvider;
+import org.gvsig.fmap.dal.exception.InitializeException;
+import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
+import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProviderFactory;
+import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
+import org.gvsig.tools.dynobject.DynObject;
+
+public class DGNStoreProviderFactory extends AbstractFeatureStoreProviderFactory implements FeatureStoreProviderFactory{
+
+	protected DGNStoreProviderFactory(String name, String description) {
+		super(name, description);
+	}
+
+	public DataStoreProvider createProvider(DataParameters parameters,
+			DataStoreProviderServices providerServices)
+			throws InitializeException {
+		return new DGNStoreProvider((DGNOpenStoreParameters) parameters, providerServices);
+	}
+
+	public DynObject createParameters() {
+		return new DGNOpenStoreParameters();
+	}
+	
+	public int allowCreate() {
+		return NO;
+	}
+	
+	public int allowWrite() {
+		return NO;
+	}
+
+	public int allowRead() {
+		return YES;
+	}
+	
+	public int hasRasterSupport() {
+		return NO;
+	}
+	
+	public int hasTabularSupport() {
+		return YES;
+	}
+	
+	public int hasVectorialSupport() {
+		return YES;
+	}
+
+	public int allowMultipleGeometryTypes() {
+		return YES;
+	}
+	
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNOpenStoreParameters.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNOpenStoreParameters.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNOpenStoreParameters.java	(revision 509)
@@ -0,0 +1,326 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.io.File;
+import java.util.regex.Pattern;
+import org.apache.commons.lang3.StringUtils;
+
+import org.cresques.cts.IProjection;
+import org.gvsig.fmap.dal.FileHelper;
+import org.gvsig.fmap.dal.feature.EditableFeatureType;
+import org.gvsig.fmap.dal.feature.FeatureType;
+import org.gvsig.fmap.dal.feature.OpenFeatureStoreParameters;
+import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
+import org.gvsig.fmap.dal.spi.AbstractDataParameters;
+import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.tools.dynobject.DelegatedDynObject;
+
+public class DGNOpenStoreParameters extends AbstractDataParameters implements
+        FilesystemStoreParameters,
+        OpenFeatureStoreParameters {
+
+    public static final String PARAMETERS_DEFINITION_NAME = "DGN";
+
+    private static final String FIELD_FILE = "file";
+    private static final String FIELD_CRS = "CRS";
+    private static final String FIELD_XMLFILE = "XMLFile";
+    private static final String FIELD_LOAD_MODE = "LoadMode";
+    private static final String FIELD_RELOAD = "Reload";
+    private static final String FIELD_GEOMTYPE_FILTER = "geomtypeFilter";
+    private static final String FIELD_LEVEL_FILTER = "levelFilter";
+    private static final String FIELD_TEXT_FILTER = "textFilter";
+    private static final String FIELD_COLOR_FILTER = "colorFilter";
+    private static final String FIELD_STYLE_FILTER = "styleFilter";
+    private static final String FIELD_WEIGHT_FILTER = "weightFilter";
+    private static final String FIELD_TYPE_FILTER = "typeFilter";
+    private static final String FIELD_STYPE_FILTER = "stypeFilter";
+    private static final String FIELD_GROUP_FILTER = "groupFilter";
+    private static final String FIELD_ID_FILTER = "idFilter";
+    private static final String FIELD_CROP_FILTER = "cropFilter";
+    private static final String FIELD_CROPOPERATION_FILTER = "cropOperationFilter";
+    private static final String FIELD_SKYPCORRUPTGEOMETRIES_FILTER = "skipCorruptGeometries";
+    private static final String FIELD_SORT_BY_GEOMETRY_TYPE = "sortByGeometryType";
+    private static final String FIELD_LOGS_ERRORS = "logErrors";
+    private static final String FIELD_IGNORE_Z = "ignoreZ";
+    private static final String FIELD_GROUPBY = "groupby";
+//    private static final String FIELD_APPLYCONVEXHULL = "applyConvexHull";
+    private static final String FIELD_USE_Z_AS_ELEVATION = "useZAsElevation";
+    private static final String FIELD_ELEVATION_FACTOR = "elevationFactor";
+    private static final String FIELD_ROUND_ELEVATION = "roundElevation";
+
+    public static final String FIELD_LINK_FILTER_INDEX = "LinkFilterIndex";
+    public static final String FIELD_LINK_FILTER_TYPE = "LinkFilterType";
+    public static final String FIELD_LINK_FILTER_ENTITY = "LinkFilterEntity";
+    public static final String FIELD_LINK_FILTER_MS = "LinkFilterMS";
+    public static final String FIELD_LINK_FILTER_DATA = "LinkFilterData";
+
+    public static final String FIELD_GROUP_GEOMETRIES_OPERATION = "GroupGeometriesOperation";
+    public static final String FIELD_FORZE2D = "force2D";
+    
+    
+    private DelegatedDynObject parameters;
+
+    public DGNOpenStoreParameters() {
+        this(PARAMETERS_DEFINITION_NAME);
+    }
+
+    protected DGNOpenStoreParameters(String parametersDefinitionName) {
+        this(parametersDefinitionName, DGNStoreProvider.NAME);
+    }
+
+    public DGNOpenStoreParameters(String parametersDefinitionName, String name) {
+        super();
+        this.parameters = (DelegatedDynObject) FileHelper.newParameters(parametersDefinitionName);
+        this.setDynValue(DataStoreProviderServices.PROVIDER_PARAMTER_NAME, name);
+    }
+
+    public String getDataStoreName() {
+        return (String) this.getDynValue(DataStoreProviderServices.PROVIDER_PARAMTER_NAME);
+    }
+
+    public String getDescription() {
+        return this.getDynClass().getDescription();
+    }
+
+    public void setCRS(IProjection srs) {
+        setDynValue(FIELD_CRS, srs);
+    }
+
+    public void setCRS(String srs) {
+        setDynValue(FIELD_CRS, srs);
+    }
+
+    public IProjection getCRS() {
+        return (IProjection) getDynValue(FIELD_CRS);
+    }
+
+    public String getFileName() {
+        return this.getFile().getPath();
+    }
+
+    public boolean isValid() {
+        if (getCRS() == null) {
+            return false;
+        }
+        if (getFile() == null) {
+            return false;
+        }
+        return true;
+    }
+
+    public File getFile() {
+        return (File) this.getDynValue(FIELD_FILE);
+    }
+
+    public File getXMLFile() {
+        return (File) this.getDynValue(FIELD_XMLFILE);
+    }
+
+    public int getGeometryTypeFilter() {
+        Integer x = (Integer) this.getDynValue(FIELD_GEOMTYPE_FILTER);
+        if (x == null) {
+            return Geometry.TYPES.GEOMETRY;
+        }
+        return x.intValue();
+    }
+
+    public int getLoadMode() {
+        Integer x = (Integer) this.getDynValue(FIELD_LOAD_MODE);
+        if (x == null) {
+            return DGNStoreProvider.LOAD_MODE_PLAIN;
+        }
+        return x.intValue();
+    }
+    
+    public int getGroupGeometriesOperation() {
+        Integer x = (Integer) this.getDynValue(FIELD_GROUP_GEOMETRIES_OPERATION);
+        if (x == null) {
+            return DGNStoreProvider.GROUP_GEOMETRIES_NONE;
+        }
+        return x.intValue();
+    }
+    
+    public double geElevationFactor() {
+        Double x = (Double) this.getDynValue(FIELD_ELEVATION_FACTOR);
+        if (x == null) {
+            return 1;
+        }
+        return x.doubleValue();
+    }
+    
+    public int getCropOperationFilter() {
+        Integer x = (Integer) this.getDynValue(FIELD_CROPOPERATION_FILTER);
+        if (x == null) {
+            return DGNStoreProvider.CROP_OPERATION_NONE;
+        }
+        return x.intValue();
+    }
+
+    public Geometry getCropFilter() {
+        Geometry x = (Geometry) this.getDynValue(FIELD_CROP_FILTER);
+        return x;
+    }
+
+    public String getGroupBy() {
+        return (String) this.getDynValue(FIELD_GROUPBY);
+    }
+
+    public String getLevelFilter() {
+        return (String) this.getDynValue(FIELD_LEVEL_FILTER);
+    }
+
+    public String getGroupFilter() {
+        return (String) this.getDynValue(FIELD_GROUP_FILTER);
+    }
+
+    public String getTextFilter() {
+        return (String) this.getDynValue(FIELD_TEXT_FILTER);
+    }
+
+    public String getIDFilter() {
+        return (String) this.getDynValue(FIELD_ID_FILTER);
+    }
+
+    public String getTypeFilter() {
+        return (String) this.getDynValue(FIELD_TYPE_FILTER);
+    }
+
+    public String getSTypeFilter() {
+        return (String) this.getDynValue(FIELD_STYPE_FILTER);
+    }
+
+    public String getColorFilter() {
+        return (String) this.getDynValue(FIELD_COLOR_FILTER);
+    }
+
+    public String getStyleFilter() {
+        return (String) this.getDynValue(FIELD_STYLE_FILTER);
+    }
+
+    public String getWeightFilter() {
+        return (String) this.getDynValue(FIELD_WEIGHT_FILTER);
+    }
+
+    public boolean useReload() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_RELOAD);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+//    public boolean getApplyConvexHull() {
+//        Boolean x = (Boolean) this.getDynValue(FIELD_APPLYCONVEXHULL);
+//        if (x == null) {
+//            return Boolean.FALSE;
+//        }
+//        return x.booleanValue();
+//    }
+
+    public boolean getApplyRoundToElevation() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_ROUND_ELEVATION);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+     public String getLinkFilterData() {
+        return StringUtils.trimToNull((String) this.getDynValue(FIELD_LINK_FILTER_DATA));
+    }
+
+     public Pattern getLinkFilterDataAsPattern() {
+        String s = getLinkFilterData();
+        if( s == null ) {
+            return null;
+        }
+        return Pattern.compile(s);
+    }
+
+    public Integer getLinkFilterIndex() {
+        return (Integer) this.getDynValue(FIELD_LINK_FILTER_INDEX);
+    }
+
+    public Integer getLinkFilterType() {
+        return (Integer) this.getDynValue(FIELD_LINK_FILTER_TYPE);
+    }
+
+    public Integer getLinkFilterEntity() {
+        return (Integer) this.getDynValue(FIELD_LINK_FILTER_ENTITY);
+    }
+
+    public Integer getLinkFilterMS() {
+        return (Integer) this.getDynValue(FIELD_LINK_FILTER_MS);
+    }
+
+    
+    public boolean ignoreZs() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_IGNORE_Z);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+    public boolean logErrors() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_LOGS_ERRORS);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+    public boolean skipCorruptGeometries() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_SKYPCORRUPTGEOMETRIES_FILTER);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+    boolean useZAsElevation() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_USE_Z_AS_ELEVATION);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+    boolean force2D() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_FORZE2D);
+        if (x == null) {
+            return Boolean.FALSE;
+        }
+        return x.booleanValue();
+    }
+
+    public boolean sortByGeometryType() {
+        Boolean x = (Boolean) this.getDynValue(FIELD_SORT_BY_GEOMETRY_TYPE);
+        if (x == null) {
+            return Boolean.TRUE;
+        }
+        return x.booleanValue();
+    }
+
+    public void setFile(File file) {
+        this.setDynValue(FIELD_FILE, file);
+    }
+
+    public void setFile(String file) {
+        this.setDynValue(FIELD_FILE, file);
+    }
+
+    public EditableFeatureType getDefaultFeatureType() {
+        return null; //TODO ????
+    }
+
+    public void setDefaultFeatureType(FeatureType defaultFeatureType) {
+        throw new UnsupportedOperationException();
+    }
+
+    protected DelegatedDynObject getDelegatedDynObject() {
+        return parameters;
+    }
+
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFilterOperation.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFilterOperation.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/PostProcessFilterOperation.java	(revision 509)
@@ -0,0 +1,277 @@
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.util.regex.Pattern;
+import org.apache.commons.lang3.StringUtils;
+import org.gvsig.fmap.dal.feature.FeatureType;
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_CONTAINS;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_COVEREDBY;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_COVERS;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_CROSSES;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_DISJOINT;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_INTERSECT;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_NONE;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_OVERLAPS;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_TOUCHES;
+import static org.gvsig.fmap.dal.store.dgn.DGNStoreProvider.CROP_OPERATION_WITHIN;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.fmap.geom.GeometryLocator;
+import org.gvsig.fmap.geom.GeometryManager;
+import org.gvsig.fmap.geom.primitive.Point;
+import org.gvsig.fmap.geom.type.GeometryType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PostProcessFilterOperation {
+
+    private static final Logger logger = LoggerFactory.getLogger(PostProcessFilterOperation.class);
+            
+    private Pattern levelFilter = null;
+    private Pattern colorFilter = null;
+    private Pattern styleFilter = null;
+    private Pattern weighFilter = null;
+    private Pattern typeFilter = null;
+    private Pattern stypeFilter = null;
+    private Pattern idFilter = null;
+    private Pattern groupFilter = null;
+    private Pattern textFilter = null;
+    private Point pointForCheckGeometries = null;
+    private boolean hasfilter = false;
+    private boolean skipCurruptGeometries = true;
+    private int geometryTypeFilter = Geometry.TYPES.GEOMETRY;
+    private int counter_exceptions = 0;
+    private int cropOperationFilter;
+    private Geometry cropFilter = null;
+    private int ID_FIELD_LEVEL = -1;
+    private int ID_FIELD_COLOR = -1;
+    private int ID_FIELD_STYLE = -1;
+    private int ID_FIELD_WEIGHT = -1;
+    private int ID_FIELD_TYPE = -1;
+    private int ID_FIELD_STYPE = -1;
+    private int ID_FIELD_GROUP = -1;
+    private int ID_FIELD_ID = -1;
+    private int ID_FIELD_TEXT = -1;
+
+    PostProcessFilterOperation(DGNOpenStoreParameters parameters, FeatureType featureType) {
+        GeometryManager geomManager = GeometryLocator.getGeometryManager();
+
+        geometryTypeFilter = parameters.getGeometryTypeFilter();
+        skipCurruptGeometries = parameters.skipCorruptGeometries();
+        if (!StringUtils.isBlank(parameters.getLevelFilter())) {
+            this.levelFilter = Pattern.compile(parameters.getLevelFilter());
+            this.ID_FIELD_LEVEL = featureType.getIndex(DGNStoreProvider.NAME_FIELD_LEVEL);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getColorFilter())) {
+            colorFilter = Pattern.compile(parameters.getColorFilter());
+            this.ID_FIELD_COLOR = featureType.getIndex(DGNStoreProvider.NAME_FIELD_COLOR);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getStyleFilter())) {
+            styleFilter = Pattern.compile(parameters.getStyleFilter());
+            this.ID_FIELD_STYLE = featureType.getIndex(DGNStoreProvider.NAME_FIELD_STYLE);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getTypeFilter())) {
+            this.typeFilter = Pattern.compile(parameters.getTypeFilter());
+            this.ID_FIELD_TYPE = featureType.getIndex(DGNStoreProvider.NAME_FIELD_TYPE);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getSTypeFilter())) {
+            this.stypeFilter = Pattern.compile(parameters.getSTypeFilter());
+            this.ID_FIELD_STYPE = featureType.getIndex(DGNStoreProvider.NAME_FIELD_STYPE);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getWeightFilter())) {
+            weighFilter = Pattern.compile(parameters.getWeightFilter());
+            this.ID_FIELD_WEIGHT = featureType.getIndex(DGNStoreProvider.NAME_FIELD_WEIGHT);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getGroupFilter())) {
+            groupFilter = Pattern.compile(parameters.getGroupFilter());
+            this.ID_FIELD_GROUP = featureType.getIndex(DGNStoreProvider.NAME_FIELD_GROUP);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getIDFilter())) {
+            idFilter = Pattern.compile(parameters.getIDFilter());
+            this.ID_FIELD_ID = featureType.getIndex(DGNStoreProvider.NAME_FIELD_ID);
+            this.hasfilter = true;
+        }
+        if (!StringUtils.isBlank(parameters.getTextFilter())) {
+            textFilter = Pattern.compile(parameters.getTextFilter());
+            this.ID_FIELD_TEXT = featureType.getIndex(DGNStoreProvider.NAME_FIELD_TEXT);
+            this.hasfilter = true;
+        }
+        if (this.geometryTypeFilter != Geometry.TYPES.GEOMETRY) {
+            this.hasfilter = true;
+        }
+        this.cropFilter = parameters.getCropFilter();
+        if (this.cropFilter != null) {
+            this.hasfilter = true;
+        }
+        this.cropOperationFilter = parameters.getCropOperationFilter();
+        if (this.cropOperationFilter == CROP_OPERATION_NONE) {
+            this.cropFilter = null;
+        }
+        this.pointForCheckGeometries = null;
+        if (skipCurruptGeometries) {
+            try {
+                int geomSubtype = featureType.getDefaultGeometryAttribute().getGeomType().getSubType();
+                this.pointForCheckGeometries = geomManager.createPoint(1, 1, geomSubtype);
+                if (geomSubtype == Geometry.SUBTYPES.GEOM3D) {
+                    this.pointForCheckGeometries.setCoordinateAt(Geometry.DIMENSIONS.Z, 1);
+                }
+            } catch (Exception ex) {
+                this.pointForCheckGeometries = null;
+            }
+        }
+    }
+    
+    public boolean hasFilter() {
+        return this.hasfilter;
+    }
+
+    private boolean match(Pattern exp, Object value) {
+        if (value == null) {
+            return false;
+        }
+        return exp.matcher(value.toString()).matches();
+    }
+
+    public boolean accept(FeatureProvider data) {
+
+        if (!this.hasfilter) {
+            return true;
+        }
+
+        Geometry geometry = data.getDefaultGeometry();
+        if (this.pointForCheckGeometries != null) {
+            if (geometry != null) {
+                try {
+                    this.pointForCheckGeometries.intersects(geometry);
+                } catch (Exception ex) {
+                    // Skip geometries with problems
+                    data.setDefaultGeometry(null);
+                    geometry = null;
+                }
+            }
+        }
+
+        try {
+            if (levelFilter!=null && !match(levelFilter, data.get(ID_FIELD_LEVEL))) {
+                return false;
+            }
+            if (colorFilter!=null && !match(colorFilter, data.get(ID_FIELD_COLOR))) {
+                return false;
+            }
+            if (styleFilter!=null && !match(styleFilter, data.get(ID_FIELD_STYLE))) {
+                return false;
+            }
+            if (weighFilter!=null && !match(weighFilter, data.get(ID_FIELD_WEIGHT))) {
+                return false;
+            }
+            if (typeFilter!=null && !match(typeFilter, data.get(ID_FIELD_TYPE))) {
+                return false;
+            }
+            if (stypeFilter!=null && !match(stypeFilter, data.get(ID_FIELD_STYPE))) {
+                return false;
+            }
+            if (groupFilter!=null && !match(groupFilter, data.get(ID_FIELD_GROUP))) {
+                return false;
+            }
+            if (idFilter!=null && !match(idFilter, data.get(ID_FIELD_ID))) {
+                return false;
+            }
+            if (textFilter!=null && !match(textFilter, data.get(ID_FIELD_TEXT))) {
+                return false;
+            }
+
+            if (geometry != null) {
+                if (geometryTypeFilter != Geometry.TYPES.GEOMETRY) {
+                    GeometryType geomtype = geometry.getGeometryType();
+                    switch (geometryTypeFilter) {
+                        case Geometry.TYPES.POINT:
+                            if (!geomtype.isTypeOf(Geometry.TYPES.POINT)
+                                    && !geomtype.isTypeOf(Geometry.TYPES.MULTIPOINT)) {
+                                return false;
+                            }
+                            break;
+                        case Geometry.TYPES.CURVE:
+                            if (!geomtype.isTypeOf(Geometry.TYPES.CURVE)
+                                    && !geomtype.isTypeOf(Geometry.TYPES.MULTICURVE)) {
+                                return false;
+                            }
+                            break;
+                        case Geometry.TYPES.SURFACE:
+                            if (!geomtype.isTypeOf(Geometry.TYPES.SURFACE)
+                                    && !geomtype.isTypeOf(Geometry.TYPES.MULTISURFACE)) {
+                                return false;
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                if (this.cropFilter != null) {
+                    switch (this.cropOperationFilter) {
+                        case CROP_OPERATION_CONTAINS:
+                            if (!this.cropFilter.contains(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_COVEREDBY:
+                            if (!this.cropFilter.coveredBy(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_COVERS:
+                            if (!this.cropFilter.covers(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_CROSSES:
+                            if (!this.cropFilter.crosses(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_DISJOINT:
+                            if (!this.cropFilter.disjoint(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_INTERSECT:
+                            if (!this.cropFilter.intersects(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_OVERLAPS:
+                            if (!this.cropFilter.overlaps(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_TOUCHES:
+                            if (!this.cropFilter.touches(geometry)) {
+                                return false;
+                            }
+                            break;
+                        case CROP_OPERATION_WITHIN:
+                            if (!this.cropFilter.within(geometry)) {
+                                return false;
+                            }
+                            break;
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            if (++counter_exceptions < 10) {
+                logger.warn("Can't filter data, accept it.", ex);
+            } else if (counter_exceptions == 10) {
+                logger.warn("Can't filter data, accept it.", ex);
+                logger.warn("Too many exceptions, dont show more.");
+            }
+            return true;
+        }
+        return true;
+    }
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNLibrary.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNLibrary.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/DGNLibrary.java	(revision 509)
@@ -0,0 +1,100 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.gvsig.fmap.dal.DALFileLibrary;
+import org.gvsig.fmap.dal.DALFileLocator;
+import org.gvsig.fmap.dal.DALLibrary;
+import org.gvsig.fmap.dal.DALLocator;
+import org.gvsig.fmap.dal.FileHelper;
+import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
+import org.gvsig.metadata.MetadataLibrary;
+import org.gvsig.metadata.exceptions.MetadataException;
+import org.gvsig.tools.library.AbstractLibrary;
+import org.gvsig.tools.library.LibraryException;
+
+public class DGNLibrary extends AbstractLibrary {
+
+    @Override
+    public void doRegistration() {
+        registerAsServiceOf(DALLibrary.class);
+        require(DALFileLibrary.class);
+        require(MetadataLibrary.class);
+    }
+
+	@Override
+	protected void doInitialize() throws LibraryException {
+	}
+
+	@Override
+	protected void doPostInitialize() throws LibraryException {
+		List<Throwable> exs = new ArrayList<Throwable>();
+				
+		FileHelper.registerParametersDefinition(
+				DGNOpenStoreParameters.PARAMETERS_DEFINITION_NAME, 
+				DGNOpenStoreParameters.class,
+				"DGNParameters.xml"
+		);
+		try {
+			FileHelper.registerMetadataDefinition(
+					DGNStoreProvider.METADATA_DEFINITION_NAME, 
+					DGNStoreProvider.class,
+					"DGNMetadata.xml"
+			);
+		} catch (MetadataException e) {
+			exs.add(e);
+		}
+
+        DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator
+				.getDataManager();
+
+		try {
+			if (!dataman.getStoreProviders().contains(DGNStoreProvider.NAME)) {
+				dataman.registerStoreProviderFactory(new DGNStoreProviderFactory(DGNStoreProvider.NAME, DGNStoreProvider.DESCRIPTION));
+			}
+		} catch (RuntimeException e) {
+			exs.add(e);
+		}
+
+		try {
+			DALFileLocator.getFilesystemServerExplorerManager()
+					.registerProvider(DGNStoreProvider.NAME,
+							DGNStoreProvider.DESCRIPTION,
+							DGNFilesystemServerProvider.class);
+		} catch (RuntimeException e) {
+			exs.add(e);
+		}
+
+		if( exs.size()>0 ) {
+			throw new LibraryException(this.getClass(), exs);
+		}
+	}
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/pom.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/pom.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider/pom.xml	(revision 509)
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.gvsig.dgn.provider</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+  <description>DAL provider for DGN files</description>
+  <parent>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.dgn</artifactId>
+      <version>2.0.107</version>
+  </parent>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-lang3</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.tools.lib</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.projection.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.dal.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.dal.file.lib</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.dal.spi</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.metadata.lib.basic.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.geometry.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.timesupport.lib.api</artifactId>
+        <scope>compile</scope>
+    </dependency>  
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.utils</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+
+    <!-- TESTS -->
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.tools.lib</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.compat.se</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.fmap.dal.impl</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <!--
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.fmap.geometry.generalpath</artifactId>
+      <scope>test</scope>
+    </dependency>
+    -->
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.projection.cresques.impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.timesupport.lib.impl</artifactId>
+      <scope>test</scope>
+    </dependency>   
+
+
+  </dependencies>
+  
+    <build>
+      <plugins>
+        <plugin>
+          <!-- Skip compilation tests -->
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>default-testCompile</id>
+              <phase>process-test-sources</phase>
+              <goals>
+                <goal>testCompile</goal>
+              </goals>
+              <configuration>
+                <skip>true</skip>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </build>
+    
+</project>

Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider
___________________________________________________________________
Added: svn:ignore
   + .settings
target
.classpath
.project


Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/pom.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/pom.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/pom.xml	(revision 509)
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.gvsig.dgn</artifactId>
+  <packaging>pom</packaging>
+  <name>${project.artifactId}</name>
+  <version>2.0.107</version>
+  <description>DGN support fort DAL and gvSIG</description>
+  <parent>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.desktop</artifactId>
+      <version>2.0.242</version>
+  </parent>
+  <url>https://devel.gvsig.org/redmine/projects/gvsig-dgn</url>
+
+  <scm>
+      <connection>scm:svn:https://devel.gvsig.org/svn/gvsig-dgn/org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107</connection>
+      <developerConnection>scm:svn:https://devel.gvsig.org/svn/gvsig-dgn/org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107</developerConnection>
+      <url>https://devel.gvsig.org/redmine/projects/gvsig-dgn/repository/show/org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107</url>
+  </scm>
+    <repositories>
+      <repository>
+        <id>gvsig-public-http-repository</id>
+        <name>gvSIG maven public HTTP repository</name>
+        <url>http://devel.gvsig.org/m2repo/j2se</url>
+        <releases>
+          <enabled>true</enabled>
+          <updatePolicy>daily</updatePolicy>
+          <checksumPolicy>warn</checksumPolicy>
+        </releases>
+        <snapshots>
+          <enabled>true</enabled>
+          <updatePolicy>daily</updatePolicy>
+          <checksumPolicy>warn</checksumPolicy>
+        </snapshots>
+      </repository>
+    </repositories>
+      
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-release-plugin</artifactId>
+				<configuration>
+					<tagBase>https://devel.gvsig.org/svn/gvsig-dgn/org.gvsig.dgn/tags</tagBase>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+  <dependencyManagement>
+      <dependencies>
+          <dependency>
+            <groupId>org.gvsig</groupId>
+            <artifactId>org.gvsig.dgn.provider</artifactId>
+            <version>2.0.107</version>
+          </dependency>
+          <dependency>
+            <groupId>org.gvsig</groupId>
+            <artifactId>org.gvsig.dgn.provider.legend</artifactId>
+            <version>2.0.107</version>
+          </dependency>
+          <dependency>
+            <groupId>org.gvsig</groupId>
+            <artifactId>org.gvsig.dgn.app.mainplugin</artifactId>
+            <version>2.0.107</version>
+          </dependency>
+      </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+  </dependencies>
+
+  <modules>
+    <module>org.gvsig.dgn.app</module>
+    <module>org.gvsig.dgn.provider</module>
+    <module>org.gvsig.dgn.provider.legend</module>
+  </modules>
+
+
+</project>
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/buildNumber.properties
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/buildNumber.properties	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/buildNumber.properties	(revision 509)
@@ -0,0 +1,2 @@
+#Sun Mar 31 03:24:24 CEST 2019
+buildNumber=2165
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/resources-plugin/config.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/resources-plugin/config.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/resources-plugin/config.xml	(revision 509)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<plugin-config>
+  <libraries library-dir="lib/"/>
+  <depends plugin-name="org.gvsig.app.mainplugin"/>
+  <resourceBundle name="text"/>
+  <extensions>
+     <extension class-name="org.gvsig.andami.LibraryExtension" active="false"/>
+  </extensions>
+</plugin-config>
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/assembly/gvsig-plugin-package.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/assembly/gvsig-plugin-package.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/src/main/assembly/gvsig-plugin-package.xml	(revision 509)
@@ -0,0 +1,37 @@
+<assembly>
+  <id>gvsig-plugin-package</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <baseDirectory>${project.artifactId}</baseDirectory>
+  <includeBaseDirectory>true</includeBaseDirectory>
+  <files>
+    <file>
+      <source>target/${project.artifactId}-${project.version}.jar</source>
+      <outputDirectory>lib</outputDirectory>
+    </file>
+    <file>
+      <source>target/package.info</source>
+    </file>
+  </files>
+
+  <fileSets>
+    <fileSet>
+      <directory>src/main/resources-plugin</directory>
+      <outputDirectory>.</outputDirectory>
+    </fileSet>
+  </fileSets>
+
+  <dependencySets>
+    <dependencySet>
+      <useProjectArtifact>false</useProjectArtifact>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+      <outputDirectory>lib</outputDirectory>
+      <includes>
+        <include>org.gvsig:org.gvsig.dgn.provider.legend</include>
+        <include>org.gvsig:org.gvsig.dgn.provider</include>
+      </includes>
+    </dependencySet>
+  </dependencySets>
+
+</assembly>
\ No newline at end of file
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/pom.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/pom.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin/pom.xml	(revision 509)
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.gvsig.dgn.app.mainplugin</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+  <description>DGN file format support</description>
+  <parent>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.dgn.app</artifactId>
+      <version>2.0.107</version>
+  </parent>
+
+  <dependencies>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.tools.lib</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.andami</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.dgn.provider</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.dgn.provider.legend</artifactId>
+        <scope>compile</scope>
+    </dependency>
+
+  </dependencies>
+  
+    <properties>
+        <!-- Package info property values -->
+        <!-- Default values in org.gvsig.desktop -->
+        <gvsig.package.info.name>Formats: DGN file format support</gvsig.package.info.name>
+        <gvsig.package.info.state>testing</gvsig.package.info.state>
+        <gvsig.package.info.official>true</gvsig.package.info.official>
+        <gvsig.package.info.dependencies>required: org.gvsig.app.mainplugin -ge 2.1.0-A</gvsig.package.info.dependencies>
+        <gvsig.package.info.categories>Formats,Vector</gvsig.package.info.categories>
+        <gvsig.package.info.poolURL>https://devel.gvsig.org/download/projects/gvsig-dgn/pool/</gvsig.package.info.poolURL>
+    </properties>
+  
+</project>

Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/org.gvsig.dgn.app.mainplugin
___________________________________________________________________
Added: svn:ignore
   + .settings
target
.classpath
.project
.buildNumber.properties.swp


Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/pom.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/pom.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app/pom.xml	(revision 509)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.gvsig.dgn.app</artifactId>
+  <packaging>pom</packaging>
+  <name>${project.artifactId}</name>
+  <parent>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.dgn</artifactId>
+      <version>2.0.107</version>
+  </parent>
+
+  <modules>
+    <module>org.gvsig.dgn.app.mainplugin</module>
+  </modules>
+
+
+</project>

Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.app
___________________________________________________________________
Added: svn:ignore
   + .settings
.project


Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendLibrary.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendLibrary.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendLibrary.java	(revision 509)
@@ -0,0 +1,67 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+/**
+ *
+ */
+package org.gvsig.fmap.dal.store.dgn.legend;
+
+import org.gvsig.fmap.dal.DALLibrary;
+import org.gvsig.fmap.dal.store.dgn.DGNLibrary;
+import org.gvsig.fmap.dal.store.dgn.DGNStoreProvider;
+import org.gvsig.metadata.MetadataLibrary;
+import org.gvsig.metadata.MetadataLocator;
+import org.gvsig.tools.dynobject.DynClass;
+import org.gvsig.tools.library.AbstractLibrary;
+import org.gvsig.tools.library.LibraryException;
+
+/**
+ * @author jmvivo
+ *
+ */
+public class DGNLegendLibrary extends AbstractLibrary {
+
+    @Override
+    public void doRegistration() {
+        registerAsServiceOf(DALLibrary.class);
+        require(DGNLibrary.class);
+        require(MetadataLibrary.class);
+    }
+
+	@Override
+	protected void doInitialize() throws LibraryException {
+	}
+
+	@Override
+	protected void doPostInitialize() throws LibraryException {
+		DynClass metadataDefinition = (DynClass) MetadataLocator.getMetadataManager()
+			.getDefinition(DGNStoreProvider.METADATA_DEFINITION_NAME);
+		DGNGetLegendBuilder.register(metadataDefinition);
+		DGNGetLegend.register(metadataDefinition);
+		DGNGetLabeling.register(metadataDefinition);
+	}
+}
\ No newline at end of file
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegendBuilder.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegendBuilder.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegendBuilder.java	(revision 509)
@@ -0,0 +1,68 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn.legend;
+
+import org.gvsig.fmap.dal.store.dgn.LegendBuilder;
+import org.gvsig.tools.ToolsLocator;
+import org.gvsig.tools.dynobject.AbstractDynMethod;
+import org.gvsig.tools.dynobject.DynClass;
+import org.gvsig.tools.dynobject.DynObject;
+import org.gvsig.tools.dynobject.DynObjectManager;
+import org.gvsig.tools.dynobject.exception.DynMethodException;
+import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
+
+public class DGNGetLegendBuilder extends AbstractDynMethod {
+	private static int code = DynObjectManager.NULLCODE;
+
+	static void register(DynClass DGNDynClass) {
+		if (code != DynObjectManager.NULLCODE) {
+			return;
+		}
+		code = ToolsLocator.getDynObjectManager().registerDynMethod(
+			DGNDynClass, 
+			new DGNGetLegendBuilder()
+		);
+
+	}
+	
+        public DGNGetLegendBuilder() {
+            super(LegendBuilder.DYNMETHOD_BUILDER_NAME,"DGN LegendBuilder creator");
+        }
+        
+        @Override
+	public int getCode() throws DynMethodNotSupportedException {
+		return code;
+	}
+
+        @Override
+	public Object invoke(DynObject self, Object[] args)
+			throws DynMethodException {
+		return new DGNLegendBuilder();
+	}
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendBuilder.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendBuilder.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNLegendBuilder.java	(revision 509)
@@ -0,0 +1,136 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn.legend;
+
+import java.awt.Color;
+
+import org.gvsig.fmap.dal.DataTypes;
+import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
+import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
+import org.gvsig.fmap.dal.store.dgn.DGNStoreProvider;
+import org.gvsig.fmap.dal.store.dgn.LegendBuilder;
+import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
+import org.gvsig.fmap.geom.Geometry;
+import org.gvsig.fmap.mapcontext.MapContextLocator;
+import org.gvsig.fmap.mapcontext.MapContextManager;
+import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialUniqueValueLegend;
+import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
+import org.gvsig.symbology.SymbologyLocator;
+import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.IAttrInTableLabelingStrategy;
+import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
+import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
+import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
+
+public class DGNLegendBuilder implements LegendBuilder {
+
+	private MapContextManager mapContextManager = MapContextLocator
+			.getMapContextManager();
+
+	private IVectorialUniqueValueLegend defaultLegend = null;
+	private IAttrInTableLabelingStrategy labelingStragegy = null;
+
+	public void begin() {
+		// Nothing to do
+	}
+
+	public void end() {
+		// Nothing to do
+	}
+
+	public Object getLegend() {
+		return defaultLegend;
+	}
+
+	public LegendBuilder initialize(FeatureStoreProvider store) {
+		defaultLegend = (IVectorialUniqueValueLegend) mapContextManager.createLegend(
+						IVectorialUniqueValueLegend.LEGEND_NAME);
+		defaultLegend.setShapeType(Geometry.TYPES.GEOMETRY);
+		defaultLegend
+				.setClassifyingFieldNames(new String[] { DGNStoreProvider.NAME_FIELD_COLOR });
+		defaultLegend.setClassifyingFieldTypes(new int[] { DataTypes.INT });
+
+		ISymbol myDefaultSymbol =
+				mapContextManager.getSymbolManager()
+				.createSymbol(Geometry.TYPES.GEOMETRY);
+
+		defaultLegend.setDefaultSymbol(myDefaultSymbol);
+
+		labelingStragegy = SymbologyLocator.getSymbologyManager().createAttrInTableLabelingStrategy();
+		labelingStragegy.setTextField(DGNStoreProvider.NAME_FIELD_TEXT);
+		labelingStragegy
+				.setRotationField(DGNStoreProvider.NAME_FIELD_ROTATIONTEXT);
+		labelingStragegy.setHeightField(DGNStoreProvider.NAME_FIELD_HEIGHTTEXT);
+		labelingStragegy.setUnit(1); // MapContext.NAMES[1] (meters)
+		return this;
+	}
+
+	public void process(FeatureProvider feature, DGNReader dgnReader) {
+		Integer clave = (Integer) feature.get("Color");
+		if (clave == null) {
+			return;
+		}
+
+		defaultLegend.useDefaultSymbol(false);
+		if (defaultLegend.getSymbolByValue(clave) == null) {
+			ISymbol theSymbol;
+			Color color = dgnReader.DGNLookupColor(clave.intValue());
+			theSymbol =
+					mapContextManager.getSymbolManager().createSymbol(
+					Geometry.TYPES.GEOMETRY, color);
+
+			theSymbol.setDescription(clave.toString());
+
+			if (theSymbol instanceof IMarkerSymbol) {
+				((IMarkerSymbol) theSymbol).setSize(1);
+			}
+
+			if (theSymbol instanceof ILineSymbol) {
+				ILineSymbol lineSymbol = (ILineSymbol) theSymbol;
+				lineSymbol.setLineWidth(1);
+				lineSymbol.setLineColor(color);
+			}
+
+			if (theSymbol instanceof IFillSymbol) {
+				IFillSymbol fillSymbol = (IFillSymbol) theSymbol;
+				fillSymbol.getOutline().setLineColor(color);
+				fillSymbol.getOutline().setLineWidth(1);
+				fillSymbol.setFillColor(null);
+			}
+			if (theSymbol != null) {
+				defaultLegend.addSymbol(clave, theSymbol);
+			}
+		}
+        defaultLegend.useDefaultSymbol(true);
+	}
+
+	public Object getLabeling() {
+		return labelingStragegy;
+	}
+
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLabeling.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLabeling.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLabeling.java	(revision 509)
@@ -0,0 +1,75 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn.legend;
+
+import org.gvsig.fmap.dal.exception.OpenException;
+import org.gvsig.fmap.dal.store.dgn.DGNStoreProvider;
+import org.gvsig.fmap.dal.store.dgn.LegendBuilder;
+import org.gvsig.tools.ToolsLocator;
+import org.gvsig.tools.dynobject.AbstractDynMethod;
+import org.gvsig.tools.dynobject.DynClass;
+import org.gvsig.tools.dynobject.DynObject;
+import org.gvsig.tools.dynobject.DynObjectManager;
+import org.gvsig.tools.dynobject.exception.DynMethodException;
+import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
+
+public class DGNGetLabeling extends AbstractDynMethod {
+	private static int code = DynObjectManager.NULLCODE;
+
+	static void register(DynClass DGNDynClass) {
+		if (code != DynObjectManager.NULLCODE) {
+			return;
+		}
+		code = ToolsLocator.getDynObjectManager().registerDynMethod(
+			DGNDynClass, 
+			new DGNGetLabeling()
+		);
+
+	}
+        
+        public DGNGetLabeling() {
+            super(LegendBuilder.DYNMETHOD_GETLABELING_NAME,"DGN Labeling");
+        }
+        
+        @Override
+	public int getCode() throws DynMethodNotSupportedException {
+		return code;
+	}
+
+        @Override
+	public Object invoke(DynObject self, Object[] args)
+			throws DynMethodException {
+		try {
+			return ((DGNStoreProvider) self).getLabeling();
+		} catch (OpenException e) {
+			//FIXME
+			throw new RuntimeException(e);
+		}
+	}
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegend.java
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegend.java	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/src/main/java/org/gvsig/fmap/dal/store/dgn/legend/DGNGetLegend.java	(revision 509)
@@ -0,0 +1,74 @@
+/* gvSIG. Geographic Information System of the Valencian Government
+ *
+ * Copyright (C) 2007-2008 Infrastructures and Transports Department
+ * of the Valencian Government (CIT)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ */
+
+/*
+* AUTHORS (In addition to CIT):
+* 2008 IVER T.I. S.A.   {{Task}}
+*/
+
+package org.gvsig.fmap.dal.store.dgn.legend;
+
+import org.gvsig.fmap.dal.exception.OpenException;
+import org.gvsig.fmap.dal.store.dgn.DGNStoreProvider;
+import org.gvsig.fmap.dal.store.dgn.LegendBuilder;
+import org.gvsig.tools.ToolsLocator;
+import org.gvsig.tools.dynobject.AbstractDynMethod;
+import org.gvsig.tools.dynobject.DynClass;
+import org.gvsig.tools.dynobject.DynObject;
+import org.gvsig.tools.dynobject.DynObjectManager;
+import org.gvsig.tools.dynobject.exception.DynMethodException;
+import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
+
+public class DGNGetLegend extends AbstractDynMethod {
+	private static int code = DynObjectManager.NULLCODE;
+
+	static void register(DynClass DGNDynClass) {
+		if (code != DynObjectManager.NULLCODE) {
+			return;
+		}
+		code = ToolsLocator.getDynObjectManager().registerDynMethod(
+			DGNDynClass, 
+			new DGNGetLegend()
+		);
+
+	}
+        
+        public DGNGetLegend() {
+            super(LegendBuilder.DYNMETHOD_GETLEGEND_NAME,"DGN Legend");
+        }
+        
+        @Override
+	public int getCode() throws DynMethodNotSupportedException {
+		return code;
+	}
+
+        @Override
+	public Object invoke(DynObject self, Object[] args)
+			throws DynMethodException {
+		try {
+			return ((DGNStoreProvider) self).getLegend();
+		} catch (OpenException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+}
Index: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/pom.xml
===================================================================
--- org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/pom.xml	(revision 0)
+++ org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend/pom.xml	(revision 509)
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.gvsig.dgn.provider.legend</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+  <description>DAL provider for DGN files</description>
+  <parent>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.dgn</artifactId>
+      <version>2.0.107</version>
+  </parent>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.dgn.provider</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.tools.lib</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.projection.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.dal.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.dal.spi</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.metadata.lib.basic.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.geometry.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.fmap.mapcontext.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.symbology.lib.api</artifactId>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.gvsig</groupId>
+        <artifactId>org.gvsig.timesupport.lib.api</artifactId>
+        <scope>compile</scope>
+    </dependency>  
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.utils</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+
+    <!-- TESTS -->
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.tools.lib</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.compat.se</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.fmap.dal.impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!--
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.fmap.geometry.generalpath</artifactId>
+      <scope>test</scope>
+    </dependency>
+    -->
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.projection.cresques.impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.gvsig</groupId>
+      <artifactId>org.gvsig.timesupport.lib.impl</artifactId>
+      <scope>test</scope>
+    </dependency>   
+
+
+  </dependencies>
+
+</project>

Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107/org.gvsig.dgn.provider.legend
___________________________________________________________________
Added: svn:ignore
   + .settings
target
.classpath
.project



Property changes on: org.gvsig.dgn/tags/org.gvsig.dgn-2.0.107
___________________________________________________________________
Added: svn:ignore
   + .pom.xml.swp


