Index: build.xml
===================================================================
--- build.xml	(revision 502182)
+++ build.xml	(working copy)
@@ -776,6 +776,7 @@
       <formatter type="xml" usefile="true"/>
       <classpath>
         <pathelement location="${build.dir}/test-classes"/>
+        <path refid="libs-build-classpath"/>
         <fileset dir="build">
           <include name="fop-transcoder-allinone.jar"/>
         </fileset>
@@ -789,6 +790,24 @@
     </junit>
   </target>
 
+  <target name="junit-userconfig" depends="junit-compile" if="junit.present" description="Runs FOP's user config JUnit tests">
+    <echo message="Running user config tests"/>
+    <junit dir="${basedir}" haltonfailure="${junit.haltonfailure}" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure">
+      <sysproperty key="basedir" value="${basedir}"/>
+      <sysproperty key="jawa.awt.headless" value="true"/>
+      <sysproperty key="fop.layoutengine.disabled" value="${layoutengine.disabled}"/>
+      <sysproperty key="fop.layoutengine.testset" value="standard"/>
+      <formatter type="brief" usefile="false"/>
+      <formatter type="plain" usefile="true"/>
+      <formatter type="xml" usefile="true"/>
+      <classpath>
+        <pathelement location="${build.dir}/test-classes"/>
+        <path refid="libs-run-classpath"/>
+      </classpath>
+      <test name="org.apache.fop.config.UserConfigTestSuite" todir="${junit.reports.dir}" outfile="TEST-userconfig"/>
+    </junit>
+  </target>
+
   <target name="junit-basic" depends="junit-compile" description="Runs FOP's JUnit basic tests" if="junit.present">
     <echo message="Running basic functionality tests for fop.jar"/>
     <junit dir="${basedir}" haltonfailure="${junit.haltonfailure}" fork="${junit.fork}" errorproperty="fop.junit.error" failureproperty="fop.junit.failure">
@@ -924,7 +943,7 @@
     </junit>
   </target>
 
-  <target name="junit" depends="junit-basic, junit-transcoder, junit-text-linebreak, junit-layout, junit-fotree, junit-intermediate-format" description="Runs all of FOP's JUnit tests" if="junit.present">
+  <target name="junit" depends="junit-userconfig, junit-basic, junit-transcoder, junit-text-linebreak, junit-layout, junit-fotree, junit-intermediate-format" description="Runs all of FOP's JUnit tests" if="junit.present">
     <fail>
       <condition>
         <or>
Index: src/documentation/content/xdocs/0.93/configuration.xml
===================================================================
--- src/documentation/content/xdocs/0.93/configuration.xml	(revision 502182)
+++ src/documentation/content/xdocs/0.93/configuration.xml	(working copy)
@@ -64,19 +64,21 @@
       <tr>
         <th>Element</th>
         <th>Data Type (for the value)</th>
+        <th>Description</th>
         <th>Default Value</th>
       </tr>
       <tr>
         <td>base</td>
         <td>URL or directory</td>
         <td>Specifies the base URL based on which relative URL will be resolved.</td>
+        <td>current directory</td>
       </tr>
       <tr>
         <td>font-base</td>
         <td>URL or directory</td>
         <td>Specifies the base URL based on which relative font URLs will be resolved.
-        If not specified defaults to the base URL above.
         </td>
+	<td>base URL/directory (above)</td>
       </tr>
       <tr>
         <td>hyphenation-base</td>
@@ -85,6 +87,7 @@
         files will be resolved. If not specified, support for user-supplied hyphenation 
         patterns remains disabled.
         </td>
+        <td>disabled</td>
       </tr>
       <tr>
         <td>source-resolution</td>
@@ -93,6 +96,7 @@
           Resolution in dpi (dots per inch) which is used internally to determine the pixel 
           size for SVG images and bitmap images without resolution information.
         </td>
+        <td>72 dpi</td>
       </tr>
       <tr>
         <td>target-resolution</td>
@@ -102,15 +106,27 @@
           images generated by bitmap renderers (such as the TIFF renderer) and by bitmaps
           generated by Apache Batik for filter effects and such.
         </td>
+        <td>72 dpi</td>
       </tr>
       <tr>
+        <td>strict-configuration</td>
+        <td>Boolean (true, false)</td>
+        <td>
+	  Setting this option to 'true' will cause FOP to strictly verify the contents of the
+	  FOP configuration file to ensure that defined resources (such as fonts and base
+	  URLs/directories) are valid and available to FOP.  Any errors found will cause FOP to
+	  immediately raise an exception.</td>
+        <td>false</td>
+      </tr>
+      <tr>
         <td>strict-validation</td>
         <td>Boolean (true, false)</td>
         <td>
           Setting this option to 'false' causes FOP to be more forgiving about XSL-FO validity, 
           for example, you're allowed to specify a border on a region-body which is supported 
           by some FO implementations but is non-standard. Note that such a border would 
-          currently have no effect in Apache FOP.</td>
+	  currently have no effect in Apache FOP.</td>
+        <td>true</td>
       </tr>
       <tr>
         <td>break-indent-inheritance</td>
@@ -124,6 +140,7 @@
           the desired behaviour and because the behaviour among the commercial implementations
           varies. The default for this option (i.e. false) is to behave exactly like the 
           specification describes.</td>
+        <td>false</td>
       </tr>
       <tr>
         <td>default-page-settings</td>
@@ -132,11 +149,13 @@
           Specifies the default width and height of a page if "auto" is specified 
           for either or both values. Use "height" and "width" attributes on the 
           default-page-settings element to specify the two values.</td>
+        <td>"height" 11 inches, "width" 8.26 inches</td>
       </tr>
       <tr>
         <td>renderers</td>
         <td>(see text below)</td>
         <td>Contains the configuration for each renderer. See below.</td>
+	<td>N/A</td>
       </tr>
     </table>
     <p>
@@ -145,6 +164,12 @@
     <source><![CDATA[
 <fop version="1.0">
 
+  <!-- Strict user configuration -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Strict FO validation -->
+  <strict-validation>true</strict-validation>
+
   <!-- Base URL for resolving relative URLs -->
   <base>./</base>
 
Index: src/documentation/content/xdocs/0.93/fonts.xml
===================================================================
--- src/documentation/content/xdocs/0.93/fonts.xml	(revision 502182)
+++ src/documentation/content/xdocs/0.93/fonts.xml	(working copy)
@@ -235,11 +235,15 @@
       </section>
       <section id="register">
         <title>Register Fonts with FOP</title>
-        <p>You must tell FOP how to find and use the font metrics files by registering them in the <a href="configuration.html">FOP Configuration</a>. Add entries for your custom fonts, regardless of font type, to the configuration file in a manner similar to the following:</p>
-        <source><![CDATA[<font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes"
-      embed-url="file:///C:/myfonts/FTL_____.pfb">
-  <font-triplet name="FrutigerLight" style="normal" weight="normal"/>
-</font>]]></source>
+        <p>You must tell FOP how to find and use font files by registering them in the <a href="configuration.html">FOP Configuration</a>. Add entries for your custom fonts, regardless of font type, to the configuration file in a manner similar to the following:</p>
+	<source><![CDATA[
+	<font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes">
+		<font-triplet name="FrutigerLight" style="normal" weight="normal"/>
+	</font>
+	<font embed-url="file:///C:/myfonts/FTR_____.pfb" kerning="no">
+		<font-triplet name="FrutigerRoman" style="normal" weight="normal"/>
+	</font>
+	]]></source>
         <note>Review the documentation for <a href="configuration.html">FOP Configuration</a> for instructions on making the FOP configuration available to FOP when it runs. Otherwise, FOP has no way of finding your custom font information.</note>
         <ul>
           <li>
@@ -247,7 +251,8 @@
             Relative URLs are resolved relative to the font-base property (or base) if available.
             See <a href="configuration.html">FOP: Configuration</a> for more information.
           </li>
-          <li>The "kerning" and "embed-url" attributes are optional. Kerning is currently not used at all. If embedding is off, the output will position the text correctly (from the metrics file), but it will not be displayed or printed correctly unless the viewer has the applicable font available to their local system.</li>
+	  <li>Either a "metrics-url" must be specified and/or an "embed-url".  If both are specified then the "metrics-url" will take precidence and will be used by FOP to load the font.</li>
+          <li>The "kerning" attribute is optional. Kerning is currently not used at all. If embedding is off, the output will position the text correctly (from the metrics file), but it will not be displayed or printed correctly unless the viewer has the applicable font available to their local system.</li>
           <li>When setting the embed-url attribute for Type 1 fonts, be sure to specify the PFB (actual font data), not PFM (font metrics) file that you used to generate the XML font metrics file.</li>
         </ul>
         <!--note>Cocoon users will need to setup the config, see FOPSerializer for more information.</note-->
Index: src/java/org/apache/fop/apps/FopFactory.java
===================================================================
--- src/java/org/apache/fop/apps/FopFactory.java	(revision 502182)
+++ src/java/org/apache/fop/apps/FopFactory.java	(working copy)
@@ -63,11 +63,25 @@
 
     /** Defines the default source resolution (72dpi) for FOP */
     private static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi
+    
+    /** Defines the default target resolution (72dpi) for FOP */
+    public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi
+    
     /** Defines the default page-height */
     private static final String DEFAULT_PAGE_HEIGHT = "11in";
+    
     /** Defines the default page-width */
     private static final String DEFAULT_PAGE_WIDTH = "8.26in";
+    
+    /** Defines if FOP should use strict validation for FO and user config */
+    public static final boolean DEFAULT_STRICT_FO_VALIDATION = true;
 
+    /** Defines if FOP should validate the user config strictly */
+    public static final boolean DEFAULT_STRICT_USERCONFIG_VALIDATION = true;
+    
+    /** Defines if FOP should use an alternative rule to determine text indents */
+    public static final boolean DEFAULT_BREAK_INDENT_INHERITANCE = false;
+
     /** logger instance */
     private static Log log = LogFactory.getLog(FopFactory.class);
     
@@ -97,27 +111,46 @@
     /** user configuration */
     private Configuration userConfig = null;
 
+    /** The base URL for all URL resolutions, especially for external-graphics */
+    private String baseURL;
+
     /** The base URL for all font URL resolutions */
     private String fontBaseURL;
-    
+
+    /** The base URL for all hyphen URL resolutions */
+    private String hyphenBaseURL;
+
     /**
      * FOP has the ability, for some FO's, to continue processing even if the
      * input XSL violates that FO's content model.  This is the default  
      * behavior for FOP.  However, this flag, if set, provides the user the
-     * ability for FOP to halt on all content model violations if desired.   
+     * ability for FOP to halt on all content model violations if desired.
      */ 
-    private boolean strictValidation = true;
+    private boolean strictValidation = DEFAULT_STRICT_FO_VALIDATION;
 
+    /**
+     * FOP will validate the contents of the user configuration strictly
+     * (e.g. base-urls and font urls/paths).
+     */
+    private boolean strictUserConfigValidation = DEFAULT_STRICT_USERCONFIG_VALIDATION;
+    
     /** Allows enabling kerning on the base 14 fonts, default is false */
     private boolean enableBase14Kerning = false;
     
     /** Source resolution in dpi */
     private float sourceResolution = DEFAULT_SOURCE_RESOLUTION;
+
+    /** Target resolution in dpi */
+    private float targetResolution = DEFAULT_TARGET_RESOLUTION;
+
+    /** Page height */
     private String pageHeight = DEFAULT_PAGE_HEIGHT;
+    
+    /** Page width */
     private String pageWidth = DEFAULT_PAGE_WIDTH;
 
     /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
-    private boolean breakIndentInheritanceOnReferenceAreaBoundary = false;
+    private boolean breakIndentInheritanceOnReferenceAreaBoundary = DEFAULT_BREAK_INDENT_INHERITANCE;
 
     /** Optional overriding LayoutManagerMaker */
     private LayoutManagerMaker lmMakerOverride = null;
@@ -149,6 +182,7 @@
      * are particular to a rendering run. Don't reuse instances over multiple rendering runs but
      * instead create a new one each time and reuse the FopFactory.
      * @return the newly created FOUserAgent instance initialized with default values
+     * @throws FOPException 
      */
     public FOUserAgent newFOUserAgent() {
         FOUserAgent userAgent = new FOUserAgent(this);
@@ -296,6 +330,22 @@
     }
 
     /**
+     * Sets the base URL.
+     * @param baseURL base URL
+     */
+    void setBaseURL(String baseURL) {
+        this.baseURL = baseURL;
+    }
+
+    /**
+     * Returns the base URL.
+     * @return the base URL
+     */
+    public String getBaseURL() {
+        return this.baseURL;
+    }
+
+    /**
      * Sets the font base URL.
      * @param fontBaseURL font base URL
      */
@@ -308,7 +358,20 @@
         return this.fontBaseURL;
     }
 
+    /** @return the hyphen base URL */
+    public String getHyphenBaseURL() {
+        return hyphenBaseURL;
+    }
+
     /**
+     * Sets the hyphen base URL.
+     * @param fontBaseURL font base URL
+     */
+    public void setHyphenBaseURL(String hyphenBaseURL) {
+        this.hyphenBaseURL = hyphenBaseURL;
+    }
+
+    /**
      * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
      * patterns and as backup for URI resolution performed during a rendering run. 
      * @param resolver the new URI resolver
@@ -399,15 +462,50 @@
     public float getSourcePixelUnitToMillimeter() {
         return 25.4f / getSourceResolution(); 
     }
-    
+
     /**
      * Sets the source resolution in dpi. This value is used to interpret the pixel size
      * of source documents like SVG images and bitmap images without resolution information.
      * @param dpi resolution in dpi
      */
-    public void setSourceResolution(int dpi) {
+    public void setSourceResolution(float dpi) {
         this.sourceResolution = dpi;
+        log.info("source-resolution set to: " + sourceResolution 
+                + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
     }
+
+    /** @return the resolution for resolution-dependant output */
+    public float getTargetResolution() {
+        return this.targetResolution;
+    }
+
+    /**
+     * Returns the conversion factor from pixel units to millimeters. This
+     * depends on the desired target resolution.
+     * @return float conversion factor
+     * @see #getTargetResolution()
+     */
+    public float getTargetPixelUnitToMillimeter() {
+        return 25.4f / this.targetResolution; 
+    }
+
+    /**
+     * Sets the source resolution in dpi. This value is used to interpret the pixel size
+     * of source documents like SVG images and bitmap images without resolution information.
+     * @param dpi resolution in dpi
+     */
+    public void setTargetResolution(float dpi) {
+        this.targetResolution = dpi;
+    }
+
+    /**
+     * Sets the source resolution in dpi. This value is used to interpret the pixel size
+     * of source documents like SVG images and bitmap images without resolution information.
+     * @param dpi resolution in dpi
+     */
+    public void setSourceResolution(int dpi) {
+        setSourceResolution((float)dpi);
+    }
     
     /**
      * Gets the default page-height to use as fallback,
@@ -427,6 +525,7 @@
      */
     public void setPageHeight(String pageHeight) {
         this.pageHeight = pageHeight;
+        log.info("Default page-height set to: " + pageHeight);
     }
     
     /**
@@ -447,6 +546,7 @@
      */
     public void setPageWidth(String pageWidth) {
         this.pageWidth = pageWidth;
+        log.info("Default page-width set to: " + pageWidth);
     }
     
     /**
@@ -491,14 +591,12 @@
      * @throws IOException if an I/O error occurs
      * @throws SAXException if a parsing error occurs
      */
-    public void setUserConfig(File userConfigFile)
-                throws SAXException, IOException {
+    public void setUserConfig(File userConfigFile) throws SAXException, IOException {
         try {
             DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
             setUserConfig(cfgBuilder.buildFromFile(userConfigFile));
-        } catch (ConfigurationException cfge) {
-            log.error("Error loading configuration: "
-                    + cfge.getMessage());
+        } catch (ConfigurationException e) {
+            throw new FOPException(e);
         }
     }
     
@@ -508,28 +606,27 @@
      * @throws IOException if an I/O error occurs
      * @throws SAXException if a parsing error occurs
      */
-    public void setUserConfig(String uri)
-                throws SAXException, IOException {
+    public void setUserConfig(String uri) throws SAXException, IOException
+                 {
         try {
             DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
             setUserConfig(cfgBuilder.build(uri));
-        } catch (ConfigurationException cfge) {
-            log.error("Error loading configuration: "
-                    + cfge.getMessage());
+        } catch (ConfigurationException e) {
+            throw new FOPException(e);
         }
     }
     
     /**
      * Set the user configuration.
      * @param userConfig configuration
+     * @throws FOPException if a configuration problem occurs 
      */
-    public void setUserConfig(Configuration userConfig) {
+    public void setUserConfig(Configuration userConfig) throws FOPException {
         this.userConfig = userConfig;
         try {
-            initUserConfig();
-        } catch (ConfigurationException cfge) {
-            log.error("Error initializing factory configuration: "
-                    + cfge.getMessage());
+            configure(userConfig);
+        } catch (ConfigurationException e) {            
+            throw new FOPException(e);
         }
     }
 
@@ -540,75 +637,127 @@
     public Configuration getUserConfig() {
         return userConfig;
     }
-    
+
     /**
      * Initializes user agent settings from the user configuration
      * file, if present: baseURL, resolution, default page size,...
      * 
      * @throws ConfigurationException when there is an entry that 
      *          misses the required attribute
+     * Configures the FopFactory.
+     * @param cfg Avalon Configuration Object
+     * @see org.apache.avalon.framework.configuration.Configurable
      */
-    public void initUserConfig() throws ConfigurationException {
-        log.debug("Initializing User Agent Configuration");
-        setFontBaseURL(getBaseURLfromConfig(userConfig, "font-base"));
-        final String hyphBase = getBaseURLfromConfig(userConfig, "hyphenation-base");
-        if (hyphBase != null) {
-            this.hyphResolver = new HyphenationTreeResolver() {
-                public Source resolve(String href) {
-                    return resolveURI(href, hyphBase);
-                }
-            };
+    public void configure(Configuration cfg) throws ConfigurationException {        
+        log.info("Initializing FopFactory Configuration");        
+        
+        boolean strictConfig = DEFAULT_STRICT_USERCONFIG_VALIDATION;
+        if (cfg.getChild("strict-configuration", false) != null) {
+            strictConfig = cfg.getChild("strict-configuration").getValueAsBoolean();
+            setStrictUserConfigValidation(strictConfig);
         }
-        if (userConfig.getChild("source-resolution", false) != null) {
-            this.sourceResolution 
-                = userConfig.getChild("source-resolution").getValueAsFloat(
-                        DEFAULT_SOURCE_RESOLUTION);
-            log.info("Source resolution set to: " + sourceResolution 
-                    + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
+        boolean strictFO = DEFAULT_STRICT_FO_VALIDATION;
+        if (cfg.getChild("strict-validation", false) != null) {
+            strictFO = cfg.getChild("strict-validation").getValueAsBoolean();
+            setStrictValidation(strictFO);
         }
-        if (userConfig.getChild("strict-validation", false) != null) {
-            this.strictValidation = userConfig.getChild("strict-validation").getValueAsBoolean();
+        try {
+            if( cfg.getChild("base", false) != null ) {
+                setBaseURL(getBaseURLfromConfig(cfg, "base"));
+            }
+        } catch( ConfigurationException e ) {
+            if( strictFO ) throw e;
+            log.error( e.getMessage() );
         }
-        if (userConfig.getChild("break-indent-inheritance", false) != null) {
-            this.breakIndentInheritanceOnReferenceAreaBoundary 
-                = userConfig.getChild("break-indent-inheritance").getValueAsBoolean();
+        if( cfg.getChild("font-base", false) != null ) {
+            try {
+                setFontBaseURL(getBaseURLfromConfig(cfg, "font-base"));
+            } catch( ConfigurationException e ) {
+                if( strictFO ) throw e;
+                log.error( e.getMessage() );
+            }
         }
-        Configuration pageConfig = userConfig.getChild("default-page-settings");
-        if (pageConfig.getAttribute("height", null) != null) {
-            setPageHeight(pageConfig.getAttribute("height"));
-            log.info("Default page-height set to: " + pageHeight);
+        if(cfg.getChild("hyphenation-base", false) != null) {
+            try {
+                setHyphenBaseURL(getBaseURLfromConfig(cfg, "hyphenation-base"));
+            } catch( ConfigurationException e ) {
+                if( strictFO ) throw e;
+                log.error( e.getMessage() );
+            }
         }
-        if (pageConfig.getAttribute("width", null) != null) {
-            setPageWidth(pageConfig.getAttribute("width"));
-            log.info("Default page-width set to: " + pageWidth);
+        if(cfg.getChild("source-resolution", false) != null) {
+            setSourceResolution(cfg.getChild("source-resolution").getValueAsFloat(DEFAULT_SOURCE_RESOLUTION));
         }
+        if (cfg.getChild("target-resolution", false) != null) {
+            setTargetResolution(cfg.getChild("target-resolution").getValueAsFloat(FOUserAgent.DEFAULT_TARGET_RESOLUTION));
+        }
+        if (cfg.getChild("break-indent-inheritance", false) != null) {
+            setBreakIndentInheritanceOnReferenceAreaBoundary(
+                    cfg.getChild("break-indent-inheritance").getValueAsBoolean());
+        }        
+        Configuration pageConfig = cfg.getChild("default-page-settings");
+        if( pageConfig != null ) {
+            if (pageConfig.getAttribute("height", null) != null) {
+                setPageHeight(pageConfig.getAttribute("height",DEFAULT_PAGE_HEIGHT));
+            }
+            if (pageConfig.getAttribute("width", null) != null) {
+                setPageWidth(pageConfig.getAttribute("width",DEFAULT_PAGE_WIDTH));
+            }
+        } else {
+            setPageHeight(DEFAULT_PAGE_HEIGHT);
+            setPageWidth(DEFAULT_PAGE_WIDTH);            
+        }
     }
 
+
     /**
      * Retrieves and verifies a base URL.
      * @param cfg The Configuration object to retrieve the base URL from
      * @param name the element name for the base URL
      * @return the requested base URL or null if not available
-     */
-    public static String getBaseURLfromConfig(Configuration cfg, String name) {
+     * @throws ConfigurationException 
+     */    
+    public static String getBaseURLfromConfig(Configuration cfg, String name)
+    throws ConfigurationException {
         if (cfg.getChild(name, false) != null) {
             try {
                 String cfgBaseDir = cfg.getChild(name).getValue(null);
                 if (cfgBaseDir != null) {
                     File dir = new File(cfgBaseDir);
-                    if (dir.isDirectory()) {
+                    if (!dir.exists()) {
+                        throw new ConfigurationException("Base URL '" + name +
+                                "' references non-existent resource '" +
+                                cfgBaseDir + "'");
+                    } else if (dir.isDirectory()) {
                         cfgBaseDir = dir.toURL().toExternalForm(); 
                     }
                 }
                 log.info(name + " set to: " + cfgBaseDir);
                 return cfgBaseDir;
             } catch (MalformedURLException mue) {
-                log.error("Base URL in user config is malformed!");
+                throw new ConfigurationException("Base URL '" + name + "' in user config is malformed!");
             }
         }
         return null;
     }
 
+    /**
+     * Is the user configuration to be validated?
+     * @param strictUserConfigValidation strict user config validation
+     * @return if the user configuration should be validated
+     */
+    public void setStrictUserConfigValidation(boolean strictUserConfigValidation) {
+        this.strictUserConfigValidation = strictUserConfigValidation;
+    }
+
+    /**
+     * Is the user configuration to be validated?
+     * @return if the user configuration should be validated
+     */
+    public boolean validateUserConfigStrictly() {
+        return this.strictUserConfigValidation;
+    }
+
     //------------------------------------------- URI resolution
 
     /**
@@ -700,5 +849,4 @@
         }
         return colorSpace;
     }
-    
-}
+}
\ No newline at end of file
Index: src/java/org/apache/fop/apps/FOURIResolver.java
===================================================================
--- src/java/org/apache/fop/apps/FOURIResolver.java	(revision 502182)
+++ src/java/org/apache/fop/apps/FOURIResolver.java	(working copy)
@@ -84,7 +84,7 @@
             try {
                 absoluteURL = f.toURL();
             } catch (MalformedURLException mfue) {
-                log.error("Could not convert filename to URL: " + mfue.getMessage(), mfue); 
+                log.error("Could not convert filename to URL: " + mfue.getMessage()); 
             }
         } else {
             URL baseURL = toBaseURL(base);
@@ -98,7 +98,7 @@
                         // the href contains only a path then file: is assumed
                         absoluteURL = new URL("file:" + href);
                     } catch (MalformedURLException mfue) {
-                        log.error("Error with URL '" + href + "': " + mue.getMessage(), mue);
+                        log.error("Error with URL '" + href + "': " + mue.getMessage());
                         return null;
                     }
                 }
@@ -137,7 +137,7 @@
                     }
                     absoluteURL = new URL(baseURL, href);
                 } catch (MalformedURLException mfue) {
-                    log.error("Error with URL '" + href + "': " + mfue.getMessage(), mfue);
+                    log.error("Error with URL '" + href + "': " + mfue.getMessage());
                     return null;
                 }
             }
@@ -155,7 +155,7 @@
             //Note: This is on "debug" level since the caller is supposed to handle this
             log.debug("File not found: " + effURL);
         } catch (java.io.IOException ioe) {
-            log.error("Error with opening URL '" + href + "': " + ioe.getMessage(), ioe);
+            log.error("Error with opening URL '" + href + "': " + ioe.getMessage());
         }
         return null;
     }
Index: src/java/org/apache/fop/apps/FOUserAgent.java
===================================================================
--- src/java/org/apache/fop/apps/FOUserAgent.java	(revision 502182)
+++ src/java/org/apache/fop/apps/FOUserAgent.java	(working copy)
@@ -67,7 +67,7 @@
 public class FOUserAgent {
 
     /** Defines the default target resolution (72dpi) for FOP */
-    public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi
+    public static final float DEFAULT_TARGET_RESOLUTION = FopFactory.DEFAULT_TARGET_RESOLUTION;
 
     private static Log log = LogFactory.getLog("FOP");
 
@@ -109,11 +109,12 @@
     
     /**
      * Default constructor
+     * @throws FOPException 
      * @see org.apache.fop.apps.FopFactory
      * @deprecated Provided for compatibility only. Please use the methods from 
      *             FopFactory to construct FOUserAgent instances!
      */
-    public FOUserAgent() {
+    public FOUserAgent() throws FOPException {
         this(FopFactory.newInstance());
     }
     
@@ -285,14 +286,8 @@
      * @see org.apache.avalon.framework.configuration.Configurable
      */
     protected void configure(Configuration cfg) {
-        setBaseURL(FopFactory.getBaseURLfromConfig(cfg, "base"));
-        if (cfg.getChild("target-resolution", false) != null) {
-            this.targetResolution 
-                = cfg.getChild("target-resolution").getValueAsFloat(
-                        DEFAULT_TARGET_RESOLUTION);
-            log.info("Target resolution set to: " + targetResolution 
-                    + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
-        }
+        setBaseURL(factory.getBaseURL());
+        setTargetResolution(factory.getTargetResolution());
     }
     
     /**
@@ -301,12 +296,11 @@
      * @return the requested configuration subtree, null if there's no configuration
      */
     public Configuration getUserRendererConfig(String mimeType) {
-
         Configuration cfg = getFactory().getUserConfig();
         if (cfg == null || mimeType == null) {
             return null;
         }
-
+        
         Configuration userRendererConfig = null;
 
         Configuration[] cfgs
@@ -460,9 +454,21 @@
      * bitmap images generated by filter effects in Apache Batik.
      * @param dpi resolution in dpi
      */
-    public void setTargetResolution(int dpi) {
+    public void setTargetResolution(float dpi) {
         this.targetResolution = dpi;
+        log.info("target-resolution set to: " + targetResolution 
+                + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
     }
+
+    /**
+     * Sets the target resolution in dpi. This value defines the target resolution of
+     * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
+     * bitmap images generated by filter effects in Apache Batik.
+     * @param dpi resolution in dpi
+     */
+    public void setTargetResolution(int dpi) {
+        setTargetResolution((float)dpi);
+    }
     
     // ---------------------------------------------- environment-level stuff
     //                                                (convenience access to FopFactory methods)
@@ -470,7 +476,7 @@
     /** @return the font base URL */
     public String getFontBaseURL() {
         String fontBaseURL = getFactory().getFontBaseURL(); 
-        return fontBaseURL != null ? fontBaseURL : this.baseURL;
+        return fontBaseURL != null ? fontBaseURL : getBaseURL();
     }
 
     /**
@@ -541,6 +547,5 @@
     public XMLHandlerRegistry getXMLHandlerRegistry() {
         return getFactory().getXMLHandlerRegistry();
     }
-
 }
 
Index: src/java/org/apache/fop/fonts/FontSetup.java
===================================================================
--- src/java/org/apache/fop/fonts/FontSetup.java	(revision 502182)
+++ src/java/org/apache/fop/fonts/FontSetup.java	(working copy)
@@ -34,6 +34,7 @@
 import org.apache.fop.fonts.base14.CourierBoldOblique;
 import org.apache.fop.fonts.base14.Symbol;
 import org.apache.fop.fonts.base14.ZapfDingbats;
+import org.apache.fop.render.PrintRenderer;
 
 // commons logging
 import org.apache.commons.logging.Log;
@@ -44,6 +45,8 @@
 import org.apache.avalon.framework.configuration.ConfigurationException;
 
 // Java
+import java.io.File;
+import java.io.FilenameFilter;
 import java.util.List;
 
 import javax.xml.transform.Source;
@@ -247,46 +250,127 @@
             
         };
     }
+   
     /**
      * Builds a list of EmbedFontInfo objects for use with the setup() method.
+     * 
      * @param cfg Configuration object
+     * @param renderer calling Renderer object
      * @return List the newly created list of fonts
      * @throws ConfigurationException if something's wrong with the config data
      */
-    public static List buildFontListFromConfiguration(Configuration cfg)
+    public static List buildFontListFromConfiguration(Configuration cfg, PrintRenderer renderer)
             throws ConfigurationException {
         List fontList = new java.util.ArrayList();
-        Configuration[] font = cfg.getChild("fonts").getChildren("font");
-        for (int i = 0; i < font.length; i++) {
-            Configuration[] triple = font[i].getChildren("font-triplet");
-            List tripleList = new java.util.ArrayList();
-            for (int j = 0; j < triple.length; j++) {
-                int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
-                tripleList.add(FontInfo.createFontKey(triple[j].getAttribute("name"),
-                                               triple[j].getAttribute("style"),
-                                               weight));
-            }
-
-            EmbedFontInfo efi;
-            efi = new EmbedFontInfo(font[i].getAttribute("metrics-url", null),
-                                    font[i].getAttributeAsBoolean("kerning", false),
-                                    tripleList, font[i].getAttribute("embed-url", null));
-
-            if (log.isDebugEnabled()) {
-                log.debug("Adding font " + efi.getEmbedFile()
-                          + ", metric file " + efi.getMetricsFile());
-                for (int j = 0; j < tripleList.size(); ++j) {
-                    FontTriplet triplet = (FontTriplet) tripleList.get(j);
-                    log.debug("Font triplet "
-                              + triplet.getName() + ", "
-                              + triplet.getStyle() + ", "
-                              + triplet.getWeight());
+               
+        FontResolver fontResolver = renderer.getFontResolver();
+        if (fontResolver == null) {
+            //Ensure that we have minimal font resolution capabilities
+            fontResolver = FontSetup.createMinimalFontResolver();
+        }
+       
+        boolean strictUserConfigValidation = renderer.getUserAgent().getFactory().validateUserConfigStrictly();
+        
+        Configuration[] fonts = cfg.getChildren("fonts");
+        for( int f = 0; f < fonts.length; f++ ) {
+                
+            Configuration[] font = fonts[f].getChildren("font");
+            for (int i = 0; i < font.length; i++) {
+    
+                String metricsUrl = font[i].getAttribute("metrics-url", null);
+                String embedUrl = font[i].getAttribute("embed-url", null);
+    
+                if( metricsUrl == null && embedUrl == null ) {
+                    if( strictUserConfigValidation ) {
+                        throw new ConfigurationException( "Font configuration without metric-url or embed-url" );
+                    }
+                    log.error("Font configuration without metric-url or embed-url");
+                    continue;
                 }
+                
+                if( metricsUrl != null && fontResolver.resolve(metricsUrl) == null ) {
+                    if( strictUserConfigValidation ) {
+                        throw new ConfigurationException( "Failed to resolve font metric-url '"
+                            + metricsUrl + "'" );                    
+                    }
+                    log.error("Failed to resolve font metric-url '" + metricsUrl + "'");
+                    continue;
+                }
+                
+                if( embedUrl != null && fontResolver.resolve(embedUrl) == null ) {
+                    if( strictUserConfigValidation ) {
+                        throw new ConfigurationException( "Failed to resolve font with embed-url '"
+                                + embedUrl + "'" );
+                    }
+                    log.error("Failed to resolve font with embed-url '" + embedUrl + "'" );
+                    continue;
+                }
+            
+                boolean useKerning = font[i].getAttributeAsBoolean("kerning", false);
+    
+                Configuration[] triple = font[i].getChildren("font-triplet");
+                List tripleList = new java.util.ArrayList();
+                for (int j = 0; j < triple.length; j++) {
+                    String name = triple[j].getAttribute("name");
+                    if( name == null ) {
+                        if( strictUserConfigValidation ) {
+                            throw new ConfigurationException( "font-triplet without name" );
+                        }
+                        log.error("font-triplet without name" );
+                        continue;
+                    }
+                    
+                    String weightStr = triple[j].getAttribute("weight");
+                    if( weightStr == null ) {
+                        if( strictUserConfigValidation ) {
+                            throw new ConfigurationException( "font-triplet without weight" );
+                        }
+                        log.error("font-triplet without weight" );
+                        continue;
+                    }
+                    int weight = FontUtil.parseCSS2FontWeight(weightStr);
+    
+                    String style = triple[j].getAttribute("style");
+                    if( style == null ) {
+                        if( strictUserConfigValidation ) {
+                            throw new ConfigurationException( "font-triplet without style" );
+                        }
+                        log.error("font-triplet without style" );
+                        continue;
+                    }
+                    
+                    tripleList.add(FontInfo.createFontKey(name,
+                            style, weight));
+                }
+    
+                EmbedFontInfo configFontInfo = new EmbedFontInfo(metricsUrl, 
+                        useKerning, tripleList, embedUrl);
+                
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding font " + configFontInfo.getEmbedFile()
+                            + ", metric file " + configFontInfo.getMetricsFile());
+                    for (int j = 0; j < tripleList.size(); ++j) {
+                        FontTriplet triplet = (FontTriplet) tripleList.get(j);
+                        log.debug("Font triplet "
+                                    + triplet.getName() + ", "
+                                    + triplet.getStyle() + ", "
+                                    + triplet.getWeight());
+                    }
+                }
+                fontList.add(configFontInfo);
             }
-
-            fontList.add(efi);
         }
         return fontList;
+    }    
+
+    /**
+     * Builds a list of EmbedFontInfo objects for use with the setup() method.
+     * 
+     * @param cfg Configuration object
+     * @return List the newly created list of fonts
+     * @throws ConfigurationException if something's wrong with the config data
+     */
+    public static List buildFontListFromConfiguration(Configuration cfg) throws ConfigurationException {
+        return buildFontListFromConfiguration(cfg, null);
     }
-}
-
+}
\ No newline at end of file
Index: src/java/org/apache/fop/render/AbstractRenderer.java
===================================================================
--- src/java/org/apache/fop/render/AbstractRenderer.java	(revision 502182)
+++ src/java/org/apache/fop/render/AbstractRenderer.java	(working copy)
@@ -88,7 +88,7 @@
     /**
      * user agent
      */
-    protected FOUserAgent userAgent;
+    protected FOUserAgent userAgent = null;
 
     /**
      * block progression position
@@ -135,6 +135,13 @@
         userAgent = agent;
     }
 
+    /**
+     *  @see org.apache.fop.render.Renderer#getUserAgent()
+     */
+    public FOUserAgent getUserAgent() {
+        return userAgent;
+    }
+
     /** @see org.apache.fop.render.Renderer#startRenderer(OutputStream) */
     public void startRenderer(OutputStream outputStream)
         throws IOException { }
Index: src/java/org/apache/fop/render/pdf/PDFRenderer.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFRenderer.java	(revision 502182)
+++ src/java/org/apache/fop/render/pdf/PDFRenderer.java	(working copy)
@@ -243,7 +243,7 @@
         this.filterMap = PDFFilterList.buildFilterMapFromConfiguration(cfg);
 
         //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg);
+        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
         if (this.fontList == null) {
             this.fontList = cfgFonts;
         } else {
Index: src/java/org/apache/fop/render/PrintRenderer.java
===================================================================
--- src/java/org/apache/fop/render/PrintRenderer.java	(revision 502182)
+++ src/java/org/apache/fop/render/PrintRenderer.java	(working copy)
@@ -41,9 +41,12 @@
     /** Font configuration */
     protected FontInfo fontInfo;
 
+    /** Font resolver */
+    protected FontResolver fontResolver = null;
+
     /** list of fonts */
     protected List fontList = null;
-
+    
     /**
      * Set up the font info
      *
@@ -51,8 +54,7 @@
      */
     public void setupFontInfo(FontInfo inFontInfo) {
         this.fontInfo = inFontInfo;
-        FontResolver resolver = new DefaultFontResolver(userAgent);
-        FontSetup.setup(fontInfo, fontList, resolver, 
+        FontSetup.setup(fontInfo, fontList, fontResolver, 
                 userAgent.getFactory().isBase14KerningEnabled());
     }
 
@@ -147,5 +149,16 @@
         
         renderXML(context, doc, ns);
     }
-    
+
+    /**
+     * Get FontResolver
+     *
+     * @return FontResolver
+     */
+    public FontResolver getFontResolver() {
+        if( this.fontResolver == null ) {
+            this.fontResolver = new DefaultFontResolver(super.userAgent);
+        }
+        return this.fontResolver;
+    }
 }
Index: src/java/org/apache/fop/render/ps/PSRenderer.java
===================================================================
--- src/java/org/apache/fop/render/ps/PSRenderer.java	(revision 502182)
+++ src/java/org/apache/fop/render/ps/PSRenderer.java	(working copy)
@@ -129,7 +129,7 @@
         this.autoRotateLandscape = cfg.getChild("auto-rotate-landscape").getValueAsBoolean(false);
 
         //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg);
+        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
         if (this.fontList == null) {
             this.fontList = cfgFonts;
         } else {
Index: src/java/org/apache/fop/render/xml/XMLRenderer.java
===================================================================
--- src/java/org/apache/fop/render/xml/XMLRenderer.java	(revision 502182)
+++ src/java/org/apache/fop/render/xml/XMLRenderer.java	(working copy)
@@ -145,7 +145,7 @@
     public void configure(Configuration cfg) throws ConfigurationException {
         super.configure(cfg);
         //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg);
+        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
         if (this.fontList == null) {
             this.fontList = cfgFonts;
         } else {
Index: test/java/org/apache/fop/render/pdf/BasePDFTestCase.java
===================================================================
--- test/java/org/apache/fop/render/pdf/BasePDFTestCase.java	(revision 502182)
+++ test/java/org/apache/fop/render/pdf/BasePDFTestCase.java	(working copy)
@@ -29,17 +29,16 @@
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.fop.AbstractFOPTestCase;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.Fop;
 import org.apache.fop.apps.FopFactory;
 import org.apache.fop.apps.MimeConstants;
 
-import junit.framework.TestCase;
-
 /**
  * Base class for automated tests that create PDF files
  */
-public class BasePDFTestCase extends TestCase {
+public class BasePDFTestCase extends AbstractFOPTestCase {
 
     /** the FopFactory */
     protected final FopFactory fopFactory = FopFactory.newInstance();
@@ -53,7 +52,10 @@
      */
     protected BasePDFTestCase(String name) {
         super(name);
+        init();
+    }
 
+    protected void init() {
         final File uc = getUserConfigFile();
 
         try {
@@ -63,7 +65,7 @@
                     + uc.getAbsolutePath() + ") failed: " + e.getMessage());
         }
     }
-
+    
     /**
      * Convert a test FO file to PDF
      * @param foFile the FO file
Index: test/test_embedurl_bad.xconf
===================================================================
--- test/test_embedurl_bad.xconf	(revision 0)
+++ test/test_embedurl_bad.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font has an embed-url that does not exist on filesystem -->
+		<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/doesnotexist.ttf">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_embedurl_malformed.xconf
===================================================================
--- test/test_embedurl_malformed.xconf	(revision 0)
+++ test/test_embedurl_malformed.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font has a malformed embed-url -->
+		<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="badprotocol:test/resources/fonts/glb12.ttf">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_fontattributes_missing.xconf
===================================================================
--- test/test_fontattributes_missing.xconf	(revision 0)
+++ test/test_fontattributes_missing.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font is without a metrics-url -->
+		<font>
+          <font-triplet name="Gladiator" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_fontbase_bad.xconf
===================================================================
--- test/test_fontbase_bad.xconf	(revision 0)
+++ test/test_fontbase_bad.xconf	(revision 0)
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./doesnotexist/</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font is with a relative metrics-url
+		     so should call upon the bad font-base -->
+        <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf">
+          <font-triplet name="Gladiator" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_fonttripletattribute_missing.xconf
===================================================================
--- test/test_fonttripletattribute_missing.xconf	(revision 0)
+++ test/test_fonttripletattribute_missing.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+        <font metrics-url="test/resources/fonts/glb12.ttf.xml">
+		  <!-- this font-triplet has a missing style attribute -->           
+          <font-triplet name="Gladiator" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_metricsurl_bad.xconf
===================================================================
--- test/test_metricsurl_bad.xconf	(revision 0)
+++ test/test_metricsurl_bad.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font has a metrics-url that does not exist on filesystem -->
+        <font metrics-url="test/resources/fonts/doesnotexist.ttf.ansi.xml">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/test_metricsurl_malformed.xconf
===================================================================
--- test/test_metricsurl_malformed.xconf	(revision 0)
+++ test/test_metricsurl_malformed.xconf	(revision 0)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+		<!-- this font has a malformed metrics-url -->
+        <font metrics-url="badprotocol:test/resources/fonts/glb12.ttf.xml">
+          <font-triplet name="Gladiator" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: status.xml
===================================================================
--- status.xml	(revision 504579)
+++ status.xml	(working copy)
@@ -28,6 +28,9 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="AD" type="fix" fixes-bug="40120,40288" due-to="Adrian Cumiskey">
+        Strict FOP user configuration checking.
+      </action>
       <action context="Code" dev="JM" type="add">
         Support for GIF images in RTF output (RTF handler, only. Does not affect the RTF library.)
       </action>
