[323185] ModelProvider doesn't refresh when web.xml file is updated XML model is not reloaded on change from outside ModelProvider API.
To force reload model unload is called.
diff --git a/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF
index b03022d..2bb74a1 100644
--- a/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF
@@ -66,6 +66,9 @@
  org.eclipse.jst.jee.ejb,
  org.eclipse.jface.text,
  org.eclipse.core.filebuffers,
- org.eclipse.jst.jee.web
+ org.eclipse.jst.jee.web,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.sse.core,
+ org.eclipse.jst.jsf.test.util
 Eclipse-LazyStart: true
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip b/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip
new file mode 100644
index 0000000..79e6011
--- /dev/null
+++ b/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip
Binary files differ
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java
index 487f677..bf7a855 100644
--- a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java
+++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java
@@ -29,6 +29,7 @@
 import org.eclipse.jst.jee.model.ejb.tests.ResourceReferenceTest;
 import org.eclipse.jst.jee.model.ejb.tests.SecurityRolesTest;
 import org.eclipse.jst.jee.model.web.tests.DeleteWebProjectTest;
+import org.eclipse.jst.jee.model.web.tests.TestWebXmlModelAfterUpdate;
 import org.eclipse.jst.jee.model.web.tests.Web25MergedModelProviderTest;
 import org.eclipse.jst.jee.model.web.tests.Web3AnnotationReaderTest;
 import org.eclipse.jst.jee.model.web.tests.WebAnnotationReaderTest;
@@ -67,6 +68,7 @@
 			suite.addTest(Web3AnnotationReaderTest.suite());
 			suite.addTest(DeleteWebProjectTest.suite());
 			suite.addTest(NotifyCloseProjectTest.suite());
+			suite.addTest(TestWebXmlModelAfterUpdate.suite());
 			suite.addTest(Web25MergedModelProviderTest.suite());
 			suite.addTest(GenerateDDTest.suite());
 			suite.addTest(EJB3MergedModelProviderFactoryTest.suite());
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java
new file mode 100644
index 0000000..46af131
--- /dev/null
+++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java
@@ -0,0 +1,268 @@
+package org.eclipse.jst.jee.model.web.tests;
+
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jst.j2ee.model.IModelProvider;
+import org.eclipse.jst.j2ee.model.ModelProviderManager;
+import org.eclipse.jst.javaee.web.Filter;
+import org.eclipse.jst.javaee.web.WebApp;
+import org.eclipse.jst.javaee.web.WebFactory;
+import org.eclipse.jst.jsf.test.util.TestUtil;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wtp.j2ee.headless.tests.plugin.HeadlessTestsPlugin;
+import org.w3c.dom.NodeList;
+
+
+@SuppressWarnings("restriction")
+public class TestWebXmlModelAfterUpdate extends TestCase
+{
+    private static final String PROJECT_NAME = "TestJSTL_Web25";
+    private static final String PROJECT_ZIP_LOCATION = "TestData/WebEditDdExternal/TestJSTL_Web25.zip";
+
+    private static final String TRINIDAD_FILTER_NAME = "trinidad";
+    private static final String TRINIDAD_FILTER_CLASS = "trinidadClass";
+    private static final String DUMMY_FILTER_NAME = "dummyFilter";
+    private static final String DUMMY_FILTER_CLASS = "dummyFilterClass";
+
+    private IProject _iProject;
+
+    public static Test suite() {
+		TestSuite suite = new TestSuite(TestWebXmlModelAfterUpdate.class);
+		return suite;
+	}
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        _iProject = TestUtil.createProjectFromZip(HeadlessTestsPlugin.getDefault().getBundle(), PROJECT_NAME, PROJECT_ZIP_LOCATION);
+    }
+
+
+    /**
+     * Writes a filter to web.xml using TextFileBuffer, then tries to remove it
+     * from web.xml using the WTP web.xml model (WebApp).
+     *
+     * @throws Exception
+     */
+    public void testModelAfterWebXmlConfigOperation () 
+    throws CoreException, UnsupportedEncodingException, IOException, 
+           MalformedTreeException, BadLocationException
+    {
+        // Use WTP web.xml model to add dummy filter
+        addDummyFilterUsingWebapp();
+
+        // Use non-WTP web.xml model to add Trinidad filter
+        addTrinidadFilterUsingNonWebapp();
+
+        // Use WTP web.xml model to remove Trinidad filter
+        // (Currently fails as Trinidad filter cannot be found in the model)
+        removeTrinidadFilterUsingWebapp();
+    }
+
+
+    private void removeTrinidadFilterUsingWebapp ()
+    {
+        final IModelProvider modelProvider = ModelProviderManager.getModelProvider(_iProject);
+        modelProvider.modify(new Runnable()
+        {
+
+            public void run ()
+            {
+                final WebApp webapp = (WebApp) modelProvider.getModelObject();
+                assertNotNull("Expected non-null webapp", webapp);
+
+                final List<Filter> filters = webapp.getFilters();
+                assertNotNull("Expected non-null list of filters", filters);
+
+                final Filter filterToRemove = findFilter(webapp, TRINIDAD_FILTER_NAME);
+                assertNotNull("Expected Trinidad filter to be non-null", filterToRemove);
+
+                assertTrue(filters.remove(filterToRemove));
+            }
+
+        }, new Path("WEB-INF/web.xml"));
+    }
+
+
+    private void addDummyFilterUsingWebapp ()
+    {
+        final IModelProvider modelProvider = ModelProviderManager.getModelProvider(_iProject);
+        modelProvider.modify(new Runnable()
+        {
+
+            public void run ()
+            {
+                final Filter filter = WebFactory.eINSTANCE.createFilter();
+                filter.setFilterName(DUMMY_FILTER_NAME);
+                filter.setFilterClass(DUMMY_FILTER_CLASS);
+
+                final WebApp webapp = (WebApp) modelProvider.getModelObject();
+                webapp.getFilters().add(filter);
+            }
+
+        }, new Path("WEB-INF/web.xml"));
+    }
+
+
+    private void addTrinidadFilterUsingNonWebapp ()
+    throws CoreException, UnsupportedEncodingException, IOException, MalformedTreeException, BadLocationException
+    {
+
+        final IFile webXmlIfile = _iProject.getFile("WebContent/WEB-INF/web.xml"); //$NON-NLS-1$
+        assertTrue(webXmlIfile.exists());
+
+        final IDOMModel model = (IDOMModel) StructuredModelManager.getModelManager().getModelForEdit(webXmlIfile);
+        assertNotNull("Expected non-null web.xml DOM model", model);
+
+        final String textToInsert = "<filter>\n"
+                                    + "    <filter-name>" + TRINIDAD_FILTER_NAME + "</filter-name>\n"
+                                    + "    <filter-class>" + TRINIDAD_FILTER_CLASS + "</filter-class>\n"
+                                    + "</filter>\n";
+
+        // Start model change
+        model.aboutToChangeModel();
+
+
+        // Change model (Add a "trinidad" filter tag before the closing </web-app>)
+
+        final IDOMDocument document = model.getDocument();
+        final String namespacePrefix = "ns"; //$NON-NLS-1$
+        final String namespace = "http://java.sun.com/xml/ns/javaee"; //$NON-NLS-1$
+        final String XPATH_WEBAPP = "//ns:web-app";
+        final MapNamespaceContext namespaceContextMap = new MapNamespaceContext();
+        namespaceContextMap.put(namespacePrefix, namespace);
+
+        final NodeList nodeList = resolveXpath(document, XPATH_WEBAPP, namespaceContextMap);
+        final IDOMNode node = (IDOMNode) nodeList.item(0);
+        final int offset = node.getEndStructuredDocumentRegion().getStartOffset(); // just before closing </web-app> tag
+
+        final TextEdit edit = new MultiTextEdit();
+        final InsertEdit insertEdit = new InsertEdit(offset, textToInsert);
+        edit.addChild(insertEdit);
+
+        FileBuffers.getTextFileBufferManager().connect(webXmlIfile.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());
+        final ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(webXmlIfile.getFullPath(), LocationKind.IFILE);
+        final IDocument idocument = buffer.getDocument();
+        edit.apply(idocument);
+
+
+        // End model change
+        model.save();
+        model.changedModel();
+    }
+
+
+    private static Filter findFilter (final WebApp webapp,
+                                      final String filterName)
+    {
+        for (final Object filter : webapp.getFilters())
+        {
+            if (((Filter) filter).getFilterName().equals(filterName))
+                return (Filter) filter;
+        }
+
+        return null;
+    }
+
+
+    private static NodeList resolveXpath (final IDOMDocument document,
+                                          final String xPathExpression,
+                                          final NamespaceContext namespaceContext)
+    {
+        final XPathFactory xPathFactory = XPathFactory.newInstance();
+        final XPath xPath = xPathFactory.newXPath();
+
+
+        if (namespaceContext != null)
+            xPath.setNamespaceContext(namespaceContext);
+
+        NodeList nodeList = null;
+        try
+        {
+            final Object nodeEval = xPath.evaluate(xPathExpression, document, XPathConstants.NODESET);
+            if (nodeEval instanceof NodeList)
+                nodeList = (NodeList) nodeEval;
+        }
+        catch (final XPathExpressionException e)
+        {
+            e.printStackTrace();
+        }
+
+        return nodeList;
+    }
+
+
+    private static class MapNamespaceContext implements NamespaceContext
+    {
+        private final Map<String, String> prefixToUri = new HashMap<String, String>();
+        private final Map<String, String> uriToPrefix = new HashMap<String, String>();
+
+
+        public String getNamespaceURI (final String prefix)
+        {
+            return prefixToUri.get(prefix);
+        }
+
+
+        public String getPrefix (final String namespaceURI)
+        {
+            return uriToPrefix.get(namespaceURI);
+        }
+
+
+        public Iterator<String> getPrefixes (final String namespaceURI)
+        {
+            return prefixToUri.keySet().iterator();
+        }
+
+
+        /**
+         * @param prefix
+         * @param uri
+         */
+        public void put (final String prefix, final String uri)
+        {
+            prefixToUri.put(prefix, uri);
+            uriToPrefix.put(uri, prefix);
+        }
+    }
+
+
+}
\ No newline at end of file