Index: mapfile.c
===================================================================
--- mapfile.c	(revision 9350)
+++ mapfile.c	(working copy)
@@ -1042,6 +1042,41 @@
 #endif
 }
 
+/************************************************************************/
+/*                         msLoadProjectionStringEPSG                   */
+/*                                                                      */
+/*      Checks fro EPSG type projection and set the axes for a          */
+/*      certain code ranges.                                            */
+/*      Use for now in WMS 1.3.0                                        */
+/************************************************************************/
+int msLoadProjectionStringEPSG(projectionObj *p, const char *value)
+{
+    p->gt.need_geotransform = MS_FALSE;
+    
+    if (strncasecmp(value, "EPSG:", 5) == 0)
+    {
+        char init_string[100];
+
+        /* translate into PROJ.4 format. */
+        sprintf( init_string, "init=epsg:%s", value+5 );
+
+        p->args = (char**)malloc(sizeof(char*) * 2);
+        p->args[0] = strdup(init_string);
+        p->numargs = 1;
+
+        if( atoi(value+5) >= 4000 && atoi(value+5) < 5000 )
+        {
+            p->args[1] = strdup("+epsgaxis=ne");
+            p->numargs = 2;
+        }
+
+        return msProcessProjection( p );
+    }
+
+    return msLoadProjectionString(p, value);
+}
+
+
 int msLoadProjectionString(projectionObj *p, char *value)
 {
   p->gt.need_geotransform = MS_FALSE;
Index: mapwfs.c
===================================================================
--- mapwfs.c	(revision 9350)
+++ mapwfs.c	(working copy)
@@ -1466,15 +1466,67 @@
       msFreeCharArray(layers, numlayers);
 
 
+    /*
+      srs is defined for wfs 1.1. If it is available. If it used to set 
+      the map projection. For EPSG codes between 4000 and 5000 
+      that coordinates order follow what is defined  in the ESPG database
+      see #2899
+  */
+    if (strncmp(paramsObj->pszVersion,"1.1",3) == 0 && paramsObj->pszSrs && pszOutputSRS)
+    {     
+          /*check if the srs passed is valid. Assuming that it is an EPSG:xxx format,
+            Or urn:ogc:def:crs:EPSG:xxx format. */
+        if (strncasecmp(paramsObj->pszSrs, "EPSG:", 5) == 0)
+        {
+            if (strcasecmp(paramsObj->pszSrs, pszOutputSRS) != 0)
+            {
+                msSetError(MS_WFSERR, 
+                           "Invalid GetFeature Request: SRSNAME value should be valid for all the TYPENAMES. Please check the capabilities and reformulate your request.",
+                           "msWFSGetFeature()");
+                return msWFSException(map, "typename", "InvalidParameterValue", paramsObj->pszVersion);
+            }
+                /*we load the projection sting in the map and possibly 
+                  set the axis order*/
+            msFreeProjection(&map->projection);
+            msLoadProjectionStringEPSG(&(map->projection), paramsObj->pszSrs);
+        }
+        else if (strncasecmp(paramsObj->pszSrs, "urn:EPSG:geographicCRC:",23) == 0)
+        {
+            char epsg_string[100];
+            const char *code;
+
+            code = paramsObj->pszSrs + 23;
+            
+            sprintf( epsg_string, "EPSG:%s", code );
+            if (strcasecmp(epsg_string, pszOutputSRS) != 0)
+            {
+                msSetError(MS_WFSERR, 
+                           "Invalid GetFeature Request: SRSNAME value should be valid for all the TYPENAMES. Please check the capabilities and reformulate your request.",
+                           "msWFSGetFeature()");
+                return msWFSException(map, "typename", "InvalidParameterValue", paramsObj->pszVersion);
+            }
+                /*we load the projection sting in the map and possibly 
+                  set the axis order*/
+            msFreeProjection(&map->projection);
+            msLoadProjectionStringEPSG(&(map->projection), epsg_string);
+        }
+    }
     /* Set map output projection to which output features should be reprojected */
-    if (pszOutputSRS && strncasecmp(pszOutputSRS, "EPSG:", 5) == 0) {
-      char szBuf[32];
-      sprintf(szBuf, "init=epsg:%.10s", pszOutputSRS+5);
-      
-      if (msLoadProjectionString(&(map->projection), szBuf) != 0) {
-        msSetError(MS_WFSERR, "msLoadProjectionString() failed", "msWFSGetFeature()");
-	return msWFSException(map, "mapserv", "NoApplicableCode", paramsObj->pszVersion);
-      }
+    else if (pszOutputSRS && strncasecmp(pszOutputSRS, "EPSG:", 5) == 0) 
+    {
+        int nTmp =0;
+        msFreeProjection(&map->projection);
+        msInitProjection(&map->projection);
+
+        if (strncmp(paramsObj->pszVersion,"1.1",3) == 0)
+          nTmp = msLoadProjectionStringEPSG(&(map->projection), pszOutputSRS);
+        else
+          nTmp = msLoadProjectionString(&(map->projection), (char*)pszOutputSRS);
+
+        if (nTmp != 0) {
+            msSetError(MS_WFSERR, "msLoadProjectionString() failed", "msWFSGetFeature()");
+            return msWFSException(map, "mapserv", "NoApplicableCode", paramsObj->pszVersion);
+        }
     }
 
     /*
Index: mapgml.c
===================================================================
--- mapgml.c	(revision 9350)
+++ mapgml.c	(working copy)
@@ -1368,6 +1368,40 @@
 #endif
 }
 
+
+/************************************************************************/
+/*                             msAxisSwapShape                          */
+/*                                                                      */
+/*      Utility function to swap x and y coordiatesn Use for now for    */
+/*      WFS 1.1.x                                                       */
+/************************************************************************/
+void msAxisSwapShape(shapeObj *shape)
+{
+    double tmp;
+    int i,j;
+
+    if (shape)
+    {
+        for(i=0; i<shape->numlines; i++) 
+        {
+            for( j=0; j<shape->line[i].numpoints; j++ ) 
+            {
+                tmp = shape->line[i].point[j].x;
+                shape->line[i].point[j].x = shape->line[i].point[j].y;
+                shape->line[i].point[j].y = tmp;
+            }
+        }
+
+        /*swap bounds*/
+        tmp = shape->bounds.minx;
+        shape->bounds.minx = shape->bounds.miny;
+        shape->bounds.miny = tmp;
+
+        tmp = shape->bounds.maxx;
+        shape->bounds.maxx = shape->bounds.maxy;
+        shape->bounds.maxy = tmp;
+    }
+}
 /*
 ** msGMLWriteWFSQuery()
 **
@@ -1391,13 +1425,42 @@
   gmlConstantObj *constant=NULL;
 
   char *namespace_prefix=NULL;
+  const char *axis = NULL;
+  int bSwapAxis = 0;
+  double tmp;
 
   msInitShape(&shape);
 
+  /*add a check to see if the map projection is set to be north-east*/
+  for( i = 0; i < map->projection.numargs; i++ )
+  {
+      if( strstr(map->projection.args[i],"epsgaxis=") != NULL )
+      {
+          axis = strstr(map->projection.args[i],"=") + 1;
+          break;
+      }
+  }
+
+  if (axis && strcasecmp(axis,"ne") == 0 )
+    bSwapAxis = 1;
+
+  
   /* Need to start with BBOX of the whole resultset */
   if (msGetQueryResultBounds(map, &resultBounds) > 0)
-    gmlWriteBounds(stream, outputformat, &resultBounds, msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE), "      ");
+  {
+      if (bSwapAxis)
+      {
+          tmp = resultBounds.minx;
+          resultBounds.minx =  resultBounds.miny;
+          resultBounds.miny = tmp;
 
+          tmp = resultBounds.maxx;
+          resultBounds.maxx =  resultBounds.maxy;
+          resultBounds.maxy = tmp;
+
+      }
+      gmlWriteBounds(stream, outputformat, &resultBounds, msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE), "      ");
+  }
   /* step through the layers looking for query results */
   for(i=0; i<map->numlayers; i++) {
 
@@ -1471,7 +1534,10 @@
             msIO_fprintf(stream, "      <%s gml:id=\"%s.%s\">\n", layerName, lp->name, shape.values[featureIdIndex]);
         } else
           msIO_fprintf(stream, "      <%s>\n", layerName);
-                    
+              
+        if (bSwapAxis)
+          msAxisSwapShape(&shape);
+
         /* write the feature geometry and bounding box */
         if(!(geometryList && geometryList->numgeometries == 1 && strcasecmp(geometryList->geometries[0].name, "none") == 0)) {
 #ifdef USE_PROJ
Index: mapows.h
===================================================================
--- mapows.h	(revision 9350)
+++ mapows.h	(working copy)
@@ -106,6 +106,7 @@
   char *pszBbox; /* only used with a Get Request */
   char *pszOutputFormat; /* only used with DescibeFeatureType */
   char *pszFeatureId;
+  char *pszSrs;
 
 } wfsParamsObj;
 
Index: mapproject.h
===================================================================
--- mapproject.h	(revision 9350)
+++ mapproject.h	(working copy)
@@ -74,6 +74,7 @@
 MS_DLL_EXPORT int msInitProjection(projectionObj *p);
 MS_DLL_EXPORT int msProcessProjection(projectionObj *p);
 MS_DLL_EXPORT int msLoadProjectionString(projectionObj *p, char *value);
+MS_DLL_EXPORT int msLoadProjectionStringEPSG(projectionObj *p, const char *value);
 MS_DLL_EXPORT char *msGetProjectionString(projectionObj *proj);
 MS_DLL_EXPORT void msAxisNormalizePoints( projectionObj *proj, int count,
                                           double *x, double *y );

