/**
  * @param <K>
  * @param properties
  * @param subType
  * @param defaultResolver
  */
 @SuppressWarnings("unchecked")
 public <K extends CRSResource<T>> AbstractCRSProvider(
     Properties properties, Class<K> subType, CRSResource<T> defaultResolver) {
   if (properties == null) {
     throw new IllegalArgumentException("The properties may not be null.");
   }
   String className = properties.getProperty("CRS_RESOURCE");
   if (className == null || "".equals(className.trim())) {
     if (defaultResolver != null) {
       LOG.logWarning(
           "Found no configured CRS-Resource to use, trying default: "
               + defaultResolver.getClass().getCanonicalName());
       resolver = defaultResolver;
     } else {
       LOG.logDebug(
           "Found no configured CRS-Resource and no default crs resource supplied, hoping for the set method.");
     }
   } else {
     try {
       Class<?> tc = null;
       if (subType == null) {
         StringBuilder sb = new StringBuilder("No subtype suplied trying to use ");
         if (defaultResolver != null) {
           sb.append(" the default resolver: ");
           tc = defaultResolver.getClass();
         } else {
           tc = CRSResource.class;
         }
         sb.append(tc.getCanonicalName()).append(" to create a subtype from. ");
         LOG.logWarning(sb.toString());
       } else {
         tc = subType.getClass();
       }
       // use reflection to instantiate the configured provider.
       Class<?> t = Class.forName(className);
       t.asSubclass(tc);
       LOG.logDebug("Trying to load configured CRS provider from classname: " + className);
       Constructor<?> constructor = t.getConstructor(this.getClass(), Properties.class);
       if (constructor == null) {
         LOG.logError(
             "No constructor ( "
                 + this.getClass()
                 + ", Properties.class) found in class:"
                 + className);
       } else {
         resolver = (K) constructor.newInstance(this, properties);
       }
     } catch (InstantiationException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()));
     } catch (IllegalAccessException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (ClassNotFoundException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (SecurityException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (NoSuchMethodException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (IllegalArgumentException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (InvocationTargetException e) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage()), e);
     } catch (Throwable t) {
       LOG.logError(
           Messages.getMessage("CRS_CONFIG_INSTANTIATION_ERROR", className, t.getMessage()), t);
     } finally {
       if (resolver == null) {
         LOG.logInfo("The configured class: " + className + " was not instantiated.");
         if (defaultResolver != null) {
           LOG.logInfo(
               "Trying to instantiate the default resolver: "
                   + defaultResolver.getClass().getCanonicalName());
           resolver = defaultResolver;
         } else {
           LOG.logWarning("No default crs resource supplied, hoping for the set method.");
         }
       }
     }
   }
 }
 public CoordinateSystem getCRSByID(String id) throws CRSConfigurationException {
   if (resolver == null) {
     throw new CRSConfigurationException("No resolver initialized, this may not be.");
   }
   CoordinateSystem result = null;
   if (id != null && !"".equals(id.trim())) {
     LOG.logDebug("Trying to load crs with id: " + id + " from cache.");
     if (LOG.isDebug()) {
       LOG.logDebug(cachedIdentifiables.keySet().toString());
     }
     if (cachedIdentifiables.containsKey(id)) {
       Identifiable r = cachedIdentifiables.get(id);
       LOG.logDebug("Found Identifiable: " + r.getIdAndName() + " from given id: " + id);
       if (!(r instanceof CoordinateSystem)) {
         LOG.logError(
             "Found Identifiable: "
                 + r.getIdAndName()
                 + " but it is not a coordinate system, your db is inconsistend return null.");
         r = null;
       }
       result = (CoordinateSystem) r;
     }
     if (result == null) {
       LOG.logDebug("No crs with id: " + id + " found in cache.");
       try {
         result = parseCoordinateSystem(resolver.getURIAsType(id));
       } catch (IOException e) {
         LOG.logDebug(e.getLocalizedMessage(), e);
         throw new CRSConfigurationException(e);
       }
       if (result != null) {
         GeographicCRS t = null;
         if (result.getType() == CoordinateSystem.COMPOUND_CRS) {
           if (((CompoundCRS) result).getUnderlyingCRS().getType()
               == CoordinateSystem.PROJECTED_CRS) {
             t = ((ProjectedCRS) ((CompoundCRS) result).getUnderlyingCRS()).getGeographicCRS();
           } else if (((CompoundCRS) result).getUnderlyingCRS().getType()
               == CoordinateSystem.GEOGRAPHIC_CRS) {
             t = (GeographicCRS) ((CompoundCRS) result).getUnderlyingCRS();
           } else {
             LOG.logWarning(
                 "Wgs84 Transformation lookup is currently only supported for GeographicCRS-chains.");
           }
         } else if (result.getType() == CoordinateSystem.PROJECTED_CRS) {
           t = ((ProjectedCRS) result).getGeographicCRS();
         } else if (result.getType() == CoordinateSystem.GEOGRAPHIC_CRS) {
           t = (GeographicCRS) result;
         } else {
           LOG.logWarning(
               "Wgs84 Transformation lookup is currently only supported for GeographicCRS-chains.");
         }
         if (t != null) {
           Helmert wgs84 = t.getGeodeticDatum().getWGS84Conversion();
           if (wgs84 == null) {
             wgs84 = resolver.getWGS84Transformation(t);
           }
           if (wgs84 != null) {
             if (wgs84.getSourceCRS() == null) {
               wgs84.setSourceCRS(t);
               addIdToCache(wgs84, true);
             }
             GeodeticDatum datum = result.getGeodeticDatum();
             if (datum != null) {
               datum.setToWGS84(wgs84);
               // update the cache as well
               addIdToCache(datum, true);
             }
           }
         }
       }
     }
   }
   if (result == null) {
     LOG.logDebug(
         "The id: "
             + id
             + " could not be mapped to a valid deegree-crs, currently projectedCRS, geographicCRS, compoundCRS and geocentricCRS are supported.");
   } else {
     /** Adding the used underlying crs's to the cache. */
     addIdToCache(result, false);
     if (result.getType() == CoordinateSystem.COMPOUND_CRS) {
       addIdToCache(((CompoundCRS) result).getUnderlyingCRS(), false);
       if (((CompoundCRS) result).getUnderlyingCRS().getType() == CoordinateSystem.PROJECTED_CRS) {
         addIdToCache(
             ((ProjectedCRS) ((CompoundCRS) result).getUnderlyingCRS()).getGeographicCRS(), false);
       }
     } else if (result.getType() == CoordinateSystem.PROJECTED_CRS) {
       addIdToCache(((ProjectedCRS) result).getGeographicCRS(), false);
     }
   }
   return result;
 }