diff --git a/pom.xml b/pom.xml
index e372339da515df616f6d0ebcc41bc1d67186e204..52674d76843ca55e6a7e0cecf18991132f2aea52 100755
--- a/pom.xml
+++ b/pom.xml
@@ -279,7 +279,7 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <version>2.13.0</version>
+            <version>2.17.0</version>
         </dependency>
     </dependencies>
 
diff --git a/src/main/java/no/nibio/vips/logic/authenticate/AuthenticationFilter.java b/src/main/java/no/nibio/vips/logic/authenticate/AuthenticationFilter.java
index aee204c1c02e3a3362d02c81af8724b3db8d5346..475c68bf2df86d301dd46a0ef92440ac85adf73b 100755
--- a/src/main/java/no/nibio/vips/logic/authenticate/AuthenticationFilter.java
+++ b/src/main/java/no/nibio/vips/logic/authenticate/AuthenticationFilter.java
@@ -1,18 +1,16 @@
 /*
- * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2022 NIBIO <http://www.nibio.no/>.
  *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 free software: you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ * 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 Affero General Public License for more
+ * details.
  *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Affero General Public License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
  *
  */
 
@@ -23,7 +21,12 @@ import java.io.IOException;
 import java.net.URLEncoder;
 import java.util.UUID;
 import javax.ejb.EJB;
-import javax.servlet.*;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -34,79 +37,69 @@ import no.nibio.vips.util.ServletUtil;
 
 /**
  * Ensures that user accessing a restricted resource is actually logged in. Redirects to login page if not
+ * 
  * @copyright 2013-2022 <a href="http://www.nibio.no">NIBIO</a>
  * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
  */
-public class AuthenticationFilter implements Filter{
-    
+public class AuthenticationFilter implements Filter {
+
     @EJB
     UserBean userBean;
 
     // The URLs that do not require login
     private String[] unprivilegedURLs;
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         this.setUnprivilegedURLs(Globals.UNPRIVILEGED_URLS);
-    } 
+    }
 
     @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
 
-        HttpServletRequest httpRequest = (HttpServletRequest)request;
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
         /*
-        // For debugging
-        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
-        String line;
-        while((line = reader.readLine()) != null)
-        {
-            System.out.println(line);
-        }*/
-        if(isUnprivilegedURL(httpRequest))
-        {
+         * // For debugging BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
+         * String line; while((line = reader.readLine()) != null) { System.out.println(line); }
+         */
+        if (isUnprivilegedURL(httpRequest)) {
             chain.doFilter(request, response);
-            //return;
-        }
-        else
-        {
+            // return;
+        } else {
             // First: Check for session variable
-            boolean clientAuthenticated = (httpRequest.getSession().getAttribute("user") != null &&  httpRequest.getSession().getAttribute("user") instanceof VipsLogicUser);
+            boolean clientAuthenticated = (httpRequest.getSession().getAttribute("user") != null
+                    && httpRequest.getSession().getAttribute("user") instanceof VipsLogicUser);
             // Then for UUID cookie that has not expired
             boolean clientRemembered = false;
             Cookie remembered = ServletUtil.getCookie(httpRequest, "rememberedUser");
-            if(remembered != null)
-            {
+            if (remembered != null) {
                 VipsLogicUser user = userBean.findVipsLogicUser(UUID.fromString(remembered.getValue()));
-                if(user != null)
-                {
+                if (user != null) {
                     httpRequest.getSession().setAttribute("user", user);
                     clientRemembered = true;
                 }
             }
-            
-            if(! clientAuthenticated && ! clientRemembered)
-            {
+
+            if (!clientAuthenticated && !clientRemembered) {
                 String nextPageDirective = "";
-                if(!httpRequest.getServletPath().equals("/login"))
-                {
+                if (!httpRequest.getServletPath().equals("/login")) {
                     String nextPage = ServletUtil.getFullRequestURI(httpRequest);
-                    nextPageDirective= "?nextPage=" + URLEncoder.encode(nextPage, "UTF-8");
+                    nextPageDirective = "?nextPage=" + URLEncoder.encode(nextPage, "UTF-8");
                 }
-                ((HttpServletResponse)response).sendRedirect(Globals.PROTOCOL + "://" + ServletUtil.getServerName(httpRequest) + "/login" + nextPageDirective);
-            }
-            else
-            {
+                ((HttpServletResponse) response).sendRedirect(Globals.PROTOCOL + "://"
+                        + ServletUtil.getServerName(httpRequest) + "/login" + nextPageDirective);
+            } else {
                 chain.doFilter(request, response);
             }
-            //return;
+            // return;
         }
     }
-    
+
     private boolean isUnprivilegedURL(HttpServletRequest request) {
         String path = request.getServletPath();
-        for (String unprivilegedURL : this.getUnprivilegedURLs()) 
-        {
-            if (path.contains(unprivilegedURL)) 
-            {
+        for (String unprivilegedURL : this.getUnprivilegedURLs()) {
+            if (path.contains(unprivilegedURL)) {
                 return true;
             }
         }
@@ -115,12 +108,10 @@ public class AuthenticationFilter implements Filter{
 
     @Override
     public void destroy() {
-        
+
     }
 
-   
 
-    
 
     /**
      * @return the upriviligerteURLer
@@ -136,6 +127,6 @@ public class AuthenticationFilter implements Filter{
         this.unprivilegedURLs = unprivilegedURLs;
     }
 
-    
-    
+
+
 }
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
index 7c79e6dd1ea1a0e21c8cdb622a191246708ec01e..99a5f3c304414d0c40f218fd7a03323e694c7631 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
@@ -61,7 +61,7 @@ import org.wololo.geojson.GeoJSONFactory;
  */
 @Stateless
 public class ObservationBean {
-    private static Logger LOGGER = LoggerFactory.getLogger(ObservationBean.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(ObservationBean.class);
     @PersistenceContext(unitName = "VIPSLogic-PU")
     EntityManager em;
     @EJB
diff --git a/src/main/java/no/nibio/vips/logic/entity/Observation.java b/src/main/java/no/nibio/vips/logic/entity/Observation.java
index 7d971682885caa3fe572f0df23933e2762e477ef..0b244dcfbb9170f91e9fe3c0eb296c30cd90d419 100755
--- a/src/main/java/no/nibio/vips/logic/entity/Observation.java
+++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2014 NIBIO <http://www.nibio.no/>.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
@@ -95,15 +95,15 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     private Boolean broadcastMessage;
     private Boolean locationIsPrivate;
     private PolygonService polygonService;
-    
+
     private ObservationDataSchema observationDataSchema;
-    
+
     private VipsLogicUser user; // Transient
     private VipsLogicUser lastEditedByUser; //
     private PointOfInterest location; // Transient
-    
+
     private Set<ObservationIllustration> observationIllustrationSet;
-    
+
     private GISEntityUtil GISEntityUtil;
     private GISUtil GISUtil;
 
@@ -156,7 +156,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         this.timeOfObservation = timeOfObservation;
     }
 
-    
+
     // Using PostGIS + Hibernate-spatial + Java Topology Suite to make this work
     /*@JsonIgnore
     @Type(type = "org.hibernate.spatial.GeometryType")
@@ -168,12 +168,12 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     public void setLocation(Point location) {
         this.location = location;
     }*/
-    
+
     public void setGeoinfos(List<Gis> geoinfo)
     {
         this.geoinfo = geoinfo;
     }
-    
+
     public void addGeoInfo(Gis geoinfo)
     {
         if(this.geoinfo == null)
@@ -182,20 +182,20 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         }
         this.geoinfo.add(geoinfo);
     }
-    
+
     @JsonIgnore
     @Transient
     public List<Gis> getGeoinfos()
     {
         return this.geoinfo;
     }
-    
-    
+
+
     public void setGeoinfo(String json)
     {
         this.setGeoinfos(this.GISEntityUtil.getGisFromGeoJSON(json));
     }
-    
+
     @Transient
     @Override
     public String getGeoinfo()
@@ -269,37 +269,37 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     @Override
     public String toString() {
         return "Observation{" +
-                "observationId=" + observationId +
-                ", timeOfObservation=" + timeOfObservation +
-                ", organism=" + organism +
-                ", cropOrganism=" + cropOrganism +
-                ", userId=" + userId +
-                ", lastEditedBy=" + lastEditedBy +
-                ", geoinfo=" + geoinfo +
-                ", observationTimeSeries=" + observationTimeSeries +
-                ", locationPointOfInterestId=" + locationPointOfInterestId +
-                ", observationHeading='" + observationHeading + '\'' +
-                ", observationText='" + observationText + '\'' +
-                ", statusTypeId=" + statusTypeId +
-                ", statusChangedByUserId=" + statusChangedByUserId +
-                ", statusChangedTime=" + statusChangedTime +
-                ", lastEditedTime=" + lastEditedTime +
-                ", statusRemarks='" + statusRemarks + '\'' +
-                ", observationData='" + observationData + '\'' +
-                ", isQuantified=" + isQuantified +
-                ", isPositive=" + isPositive +
-                ", broadcastMessage=" + broadcastMessage +
-                ", locationIsPrivate=" + locationIsPrivate +
-                ", polygonService=" + polygonService +
-                ", observationDataSchema=" + observationDataSchema +
-                ", user=" + user +
-                ", lastEditedByUser=" + lastEditedByUser +
-                ", location=" + location +
-                ", observationIllustrationSet=" + observationIllustrationSet +
-                ", GISEntityUtil=" + GISEntityUtil +
-                ", GISUtil=" + GISUtil +
-                ", source=" + source +
-                '}';
+            "observationId=" + observationId +
+            ", timeOfObservation=" + timeOfObservation +
+            ", organism=" + organism +
+            ", cropOrganism=" + cropOrganism +
+            ", userId=" + userId +
+            ", lastEditedBy=" + lastEditedBy +
+            ", geoinfo=" + geoinfo +
+            ", observationTimeSeries=" + observationTimeSeries +
+            ", locationPointOfInterestId=" + locationPointOfInterestId +
+            ", observationHeading='" + observationHeading + '\'' +
+            ", observationText='" + observationText + '\'' +
+            ", statusTypeId=" + statusTypeId +
+            ", statusChangedByUserId=" + statusChangedByUserId +
+            ", statusChangedTime=" + statusChangedTime +
+            ", lastEditedTime=" + lastEditedTime +
+            ", statusRemarks='" + statusRemarks + '\'' +
+            ", observationData='" + observationData + '\'' +
+            ", isQuantified=" + isQuantified +
+            ", isPositive=" + isPositive +
+            ", broadcastMessage=" + broadcastMessage +
+            ", locationIsPrivate=" + locationIsPrivate +
+            ", polygonService=" + polygonService +
+            ", observationDataSchema=" + observationDataSchema +
+            ", user=" + user +
+            ", lastEditedByUser=" + lastEditedByUser +
+            ", location=" + location +
+            ", observationIllustrationSet=" + observationIllustrationSet +
+            ", GISEntityUtil=" + GISEntityUtil +
+            ", GISUtil=" + GISUtil +
+            ", source=" + source +
+            '}';
     }
 
     /**
@@ -338,13 +338,13 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     public void setOrganism(Organism organism) {
         this.organism = organism;
     }
-    
+
     @JoinColumn(name = "polygon_service_id", referencedColumnName = "polygon_service_id")
     @ManyToOne
     public PolygonService getPolygonService(){
         return this.polygonService;
     }
-    
+
     public void setPolygonService(PolygonService polygonService)
     {
         this.polygonService = polygonService;
@@ -363,7 +363,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         return this.getLocationCoordinate().x;
     }
     */
-    
+
     @Override
     @Transient
     public String getName() {
@@ -480,13 +480,13 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     public void setObservationData(String observationData) {
         this.observationData = observationData;
     }
-    
+
     @Transient
     public ObservationDataSchema getObservationDataSchema()
     {
         return this.observationDataSchema != null ? this.observationDataSchema : null;
     }
-    
+
     public void setObservationDataSchema(ObservationDataSchema observationDataSchema)
     {
         this.observationDataSchema = observationDataSchema;
@@ -522,7 +522,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     public void setCropOrganism(Organism cropOrganism) {
         this.cropOrganism = cropOrganism;
     }
-    
+
     @Transient
     public Integer getCropOrganismId() {
         return this.getCropOrganism() != null ? this.getCropOrganism().getOrganismId() : null;
@@ -564,7 +564,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     }
 
     /**
-      * @return the observation time series
+     * @return the observation time series
      */
     @JoinColumn(name = "observation_time_series_id", referencedColumnName = "observation_time_series_id")
     @ManyToOne
@@ -678,7 +678,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     /**
      * Simplifies the public JSON object
      * @param locale
-     * @return 
+     * @return
      */
     public ObservationListItem getListItem(String locale, ObservationDataSchema observationDataSchema)
     {
@@ -690,41 +690,41 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
             this.location.addProperty("timestamp", this.getTimeOfObservation().getTime());
         }
         return new ObservationListItem(
-                this.getObservationId(),
-                this.userId,
-                this.user != null ? this.user.getFullName() : null,
-                this.getObservationTimeSeriesId(),
-                this.getTimeOfObservation(),
-                this.getOrganismId(),
-                ! this.getOrganism().getLocalName(locale).trim().isBlank() ? this.getOrganism().getLocalName(locale) : this.getOrganism().getLatinName(),
-                this.getCropOrganismId(),
-                ! this.getCropOrganism().getLocalName(locale).trim().isBlank() ? this.getCropOrganism().getLocalName(locale) : this.getCropOrganism().getLatinName(),
-                this.observationTimeSeries != null ? this.observationTimeSeries.getLabel() : null,
-                // Specific geoInfo trumps location. This is to be interpreted 
-                // as that the observation has been geographically masked by
-                // choice of the observer
-                this.location != null ? this.location.getPointOfInterestId() : null,
-                this.location != null ? this.location.getName() : null,
-                this.location != null && this.geoinfo == null ? this.location.getGeoJSON() : this.getGeoinfo(),
-                this.getObservationHeading(),
-                this.getObservationText(),
-                this.getBroadcastMessage(),
-                this.getLocationIsPrivate(),
-                this.getIsPositive(),
-                this.getObservationData(),
-                observationDataSchema
+            this.getObservationId(),
+            this.userId,
+            this.user != null ? this.user.getFullName() : null,
+            this.getObservationTimeSeriesId(),
+            this.getTimeOfObservation(),
+            this.getOrganismId(),
+            ! this.getOrganism().getLocalName(locale).trim().isBlank() ? this.getOrganism().getLocalName(locale) : this.getOrganism().getLatinName(),
+            this.getCropOrganismId(),
+            ! this.getCropOrganism().getLocalName(locale).trim().isBlank() ? this.getCropOrganism().getLocalName(locale) : this.getCropOrganism().getLatinName(),
+            this.observationTimeSeries != null ? this.observationTimeSeries.getLabel() : null,
+            // Specific geoInfo trumps location. This is to be interpreted
+            // as that the observation has been geographically masked by
+            // choice of the observer
+            this.location != null ? this.location.getPointOfInterestId() : null,
+            this.location != null ? this.location.getName() : null,
+            this.location != null && this.geoinfo == null ? this.location.getGeoJSON() : this.getGeoinfo(),
+            this.getObservationHeading(),
+            this.getObservationText(),
+            this.getBroadcastMessage(),
+            this.getLocationIsPrivate(),
+            this.getIsPositive(),
+            this.getObservationData(),
+            observationDataSchema
         );
     }
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(name = "last_edited_time")
-	public Date getLastEditedTime() {
-		return lastEditedTime; 
-	}
+    public Date getLastEditedTime() {
+        return lastEditedTime;
+    }
 
-	public void setLastEditedTime(Date lastEditedTime) {
-		this.lastEditedTime = lastEditedTime;
-	}
+    public void setLastEditedTime(Date lastEditedTime) {
+        this.lastEditedTime = lastEditedTime;
+    }
 
     @Column(name = "is_positive")
     public Boolean getIsPositive() {
diff --git a/src/main/java/no/nibio/vips/logic/entity/VipsLogicUser.java b/src/main/java/no/nibio/vips/logic/entity/VipsLogicUser.java
index 0d9c0f09189b5ed1e42c857df8748a611b141114..27102b4dd8893a1bc2857c365a4cec3b6a7f6446 100755
--- a/src/main/java/no/nibio/vips/logic/entity/VipsLogicUser.java
+++ b/src/main/java/no/nibio/vips/logic/entity/VipsLogicUser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2015-2019 NIBIO <http://www.nibio.no/>.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
@@ -63,7 +63,7 @@ import java.util.UUID;
     @NamedQuery(name = "VipsLogicUser.findByCompletePhoneNumber", query = "SELECT v FROM VipsLogicUser v WHERE v.phoneCountryCode || v.phone = :completePhoneNumber")
 })
 public class VipsLogicUser implements Serializable, Comparable{
-    
+
     private static final long serialVersionUID = 1L;
     private Integer userId;
     //if the field contains email address consider using this annotation to enforce field validation
@@ -93,7 +93,7 @@ public class VipsLogicUser implements Serializable, Comparable{
     private Integer vipsCoreUserId;
     private boolean approvesSmsBilling;
     private boolean freeSms;
-    
+
     private UUID userUuid;
 
     public VipsLogicUser() {
@@ -166,7 +166,7 @@ public class VipsLogicUser implements Serializable, Comparable{
     public Organization getOrganizationId() {
         return organizationId;
     }
-    
+
     @Transient
     public Integer getOrganization_id(){
         return organizationId.getOrganizationId();
@@ -255,11 +255,11 @@ public class VipsLogicUser implements Serializable, Comparable{
     @ManyToMany(fetch = FetchType.EAGER)
     @JsonIgnore
     @JoinTable(
-            name = "user_vips_logic_role",
-            joinColumns = {
-                @JoinColumn(name = "user_id")},
-            inverseJoinColumns = {
-                @JoinColumn(name = "vips_logic_role_id")}
+        name = "user_vips_logic_role",
+        joinColumns = {
+            @JoinColumn(name = "user_id")},
+        inverseJoinColumns = {
+            @JoinColumn(name = "vips_logic_role_id")}
     )
     public Set<VipsLogicRole> getVipsLogicRoles() {
         return vipsLogicRoles;
@@ -293,7 +293,7 @@ public class VipsLogicUser implements Serializable, Comparable{
         }
         return false;
     }
-    
+
     @JsonIgnore
     @Transient
     public boolean isObservationAuthority(){
@@ -304,7 +304,7 @@ public class VipsLogicUser implements Serializable, Comparable{
         }
         return false;
     }
-    
+
     @JsonIgnore
     @Transient
     public boolean isOrganismEditor() {
@@ -315,7 +315,7 @@ public class VipsLogicUser implements Serializable, Comparable{
         }
         return false;
     }
-    
+
     @JsonIgnore
     @Transient
     public boolean isAppleFruitMothAdministrator(){
@@ -326,7 +326,7 @@ public class VipsLogicUser implements Serializable, Comparable{
         }
         return false;
     }
-    
+
     @JsonIgnore
     @Transient
     public boolean isMessageAuthor(){
@@ -505,7 +505,7 @@ public class VipsLogicUser implements Serializable, Comparable{
     public boolean isFreeSms() {
         return freeSms;
     }
-    
+
 
     /**
      * @param freeSms the freeSms to set
@@ -519,6 +519,6 @@ public class VipsLogicUser implements Serializable, Comparable{
         VipsLogicUser other = (VipsLogicUser)o;
         return (this.getLastName() + ", " + this.getFirstName()).compareTo(other.getLastName() + ", " + other.getFirstName());
     }
-    
-    
+
+
 }
diff --git a/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
index 5082c7089796662fdd85982ab4ff6529e0e41b90..95d83c07dfcc4494d8fbc4022afebdff8fbb58aa 100644
--- a/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
+++ b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2018 NIBIO <http://www.nibio.no/>.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
@@ -45,26 +45,26 @@ public class ObservationListItem implements Comparable{
     private Boolean isPositive;
 
     public ObservationListItem(
-            Integer observationId,
-            Integer observerId,
-            String observerName,
-            Integer observationTimeSeriesId,
-            Date timeOfObservation,
-            Integer organismId,
-            String organismName,
-            Integer cropOrganismId,
-            String cropOrganismName,
-            String observationTimeSeriesLabel,
-            Integer poiId,
-            String poiName,
-            String geoinfo,
-            String observationHeading,
-            String observationText,
-            Boolean broadcastMessage,
-            Boolean locationIsPrivate,
-            Boolean isPositive,
-            String observationData,
-            ObservationDataSchema observationDataSchema){
+        Integer observationId,
+        Integer observerId,
+        String observerName,
+        Integer observationTimeSeriesId,
+        Date timeOfObservation,
+        Integer organismId,
+        String organismName,
+        Integer cropOrganismId,
+        String cropOrganismName,
+        String observationTimeSeriesLabel,
+        Integer poiId,
+        String poiName,
+        String geoinfo,
+        String observationHeading,
+        String observationText,
+        Boolean broadcastMessage,
+        Boolean locationIsPrivate,
+        Boolean isPositive,
+        String observationData,
+        ObservationDataSchema observationDataSchema){
         this.observationId = observationId;
         this.observerId = observerId;
         this.observerName = observerName;
@@ -86,7 +86,7 @@ public class ObservationListItem implements Comparable{
         this.observationData = observationData;
         this.observationDataSchema = observationDataSchema;
     }
-    
+
 
     @Override
     public int compareTo(Object otherOne)
@@ -97,7 +97,7 @@ public class ObservationListItem implements Comparable{
         }
         return this.getTimeOfObservation().compareTo(((ObservationListItem) otherOne).getTimeOfObservation());
     }
-    
+
     /**
      * @return the observationId
      */
diff --git a/src/main/java/no/nibio/vips/logic/service/ObservationService.java b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
index 12aa050d36c928713615101745cb370c492db080..75d4ac8ba5def7edab317ebfe851561a08c28b84 100755
--- a/src/main/java/no/nibio/vips/logic/service/ObservationService.java
+++ b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
@@ -111,24 +111,24 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(Observation[].class)
     public Response getFilteredObservations(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
-            @QueryParam("pestId") Integer pestId,
-            @QueryParam("cropId") Integer cropId,
-            @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
-            @QueryParam("from") String fromStr,
-            @QueryParam("to") String toStr,
-            @QueryParam("isPositive") Boolean isPositive
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
+        @QueryParam("pestId") Integer pestId,
+        @QueryParam("cropId") Integer cropId,
+        @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
+        @QueryParam("from") String fromStr,
+        @QueryParam("to") String toStr,
+        @QueryParam("isPositive") Boolean isPositive
     ) {
         return Response.ok().entity(getFilteredObservationsFromBackend(
-                organizationId,
-                observationTimeSeriesId,
-                pestId,
-                cropId,
-                cropCategoryId,
-                fromStr,
-                toStr,
-                isPositive
+            organizationId,
+            observationTimeSeriesId,
+            pestId,
+            cropId,
+            cropCategoryId,
+            fromStr,
+            toStr,
+            isPositive
         )).build();
     }
 
@@ -148,16 +148,16 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(ObservationListItem.class)
     public Response getFilteredObservationListItemsAsJson(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
-            @QueryParam("pestId") Integer pestId,
-            @QueryParam("cropId") Integer cropId,
-            @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
-            @QueryParam("from") String fromStr,
-            @QueryParam("to") String toStr,
-            @QueryParam("userUUID") String userUUID,
-            @QueryParam("locale") String localeStr,
-            @QueryParam("isPositive") Boolean isPositive
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
+        @QueryParam("pestId") Integer pestId,
+        @QueryParam("cropId") Integer cropId,
+        @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
+        @QueryParam("from") String fromStr,
+        @QueryParam("to") String toStr,
+        @QueryParam("userUUID") String userUUID,
+        @QueryParam("locale") String localeStr,
+        @QueryParam("isPositive") Boolean isPositive
     ) {
         return Response.ok().entity(this.getFilteredObservationListItems(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive)).build();
     }
@@ -177,21 +177,21 @@ public class ObservationService {
     @GZIP
     @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
     public Response getFilteredObservationListItemsAsXlsx(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
-            @QueryParam("pestId") Integer pestId,
-            @QueryParam("cropId") Integer cropId,
-            @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
-            @QueryParam("from") String fromStr,
-            @QueryParam("to") String toStr,
-            @QueryParam("userUUID") String userUUID,
-            @QueryParam("locale") String localeStr,
-            @QueryParam("isPositive") Boolean isPositive
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
+        @QueryParam("pestId") Integer pestId,
+        @QueryParam("cropId") Integer cropId,
+        @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
+        @QueryParam("from") String fromStr,
+        @QueryParam("to") String toStr,
+        @QueryParam("userUUID") String userUUID,
+        @QueryParam("locale") String localeStr,
+        @QueryParam("isPositive") Boolean isPositive
     ) {
         VipsLogicUser user = getVipsLogicUser(userUUID);
         ULocale locale = new ULocale(localeStr != null ? localeStr :
-                user != null ? user.getOrganizationId().getDefaultLocale() :
-                        userBean.getOrganization(organizationId).getDefaultLocale());
+            user != null ? user.getOrganizationId().getDefaultLocale() :
+                userBean.getOrganization(organizationId).getDefaultLocale());
         LOGGER.info("Generate xlsx file for observations for user {} from {} to {}", user != null ? user.getUserId() : "unregistered", fromStr, toStr);
 
         LocalDateTime now = LocalDateTime.now();
@@ -203,9 +203,9 @@ public class ObservationService {
             byte[] excelFile = ExcelFileGenerator.generateExcel(user, locale, now, fromStr, toStr, observations);
 
             return Response
-                    .ok(excelFile)
-                    .header("Content-Disposition", "attachment; filename=\"" + filenameTimestamp + "-observations.xlsx\"")
-                    .build();
+                .ok(excelFile)
+                .header("Content-Disposition", "attachment; filename=\"" + filenameTimestamp + "-observations.xlsx\"")
+                .build();
         } catch (IOException e) {
             LOGGER.error(e.getMessage());
             return Response.serverError().entity("Error generating Excel file: " + e.getMessage()).build();
@@ -213,40 +213,40 @@ public class ObservationService {
     }
 
     private List<ObservationListItem> getFilteredObservationListItems(
-            Integer organizationId,
-            Integer observationTimeSeriesId,
-            Integer pestId,
-            Integer cropId,
-            List<Integer> cropCategoryId,
-            String fromStr,
-            String toStr,
-            String userUUID,
-            String localeStr,
-            Boolean isPositive) {
+        Integer organizationId,
+        Integer observationTimeSeriesId,
+        Integer pestId,
+        Integer cropId,
+        List<Integer> cropCategoryId,
+        String fromStr,
+        String toStr,
+        String userUUID,
+        String localeStr,
+        Boolean isPositive) {
         VipsLogicUser user = getVipsLogicUser(userUUID);
         ULocale locale = new ULocale(localeStr != null ? localeStr :
-                user != null ? user.getOrganizationId().getDefaultLocale() :
-                        userBean.getOrganization(organizationId).getDefaultLocale());
+            user != null ? user.getOrganizationId().getDefaultLocale() :
+                userBean.getOrganization(organizationId).getDefaultLocale());
 
         LOGGER.info("Get filtered observations for user {}", user != null ? user.getUserId() : "<no user>");
         List<ObservationListItem> observations = getFilteredObservationsFromBackend(
-                organizationId,
-                observationTimeSeriesId,
-                pestId,
-                cropId,
-                cropCategoryId,
-                fromStr,
-                toStr,
-                isPositive,
-                user
+            organizationId,
+            observationTimeSeriesId,
+            pestId,
+            cropId,
+            cropCategoryId,
+            fromStr,
+            toStr,
+            isPositive,
+            user
         ).stream().map(obs -> {
             try {
                 return obs.getListItem(locale.getLanguage(),
-                        observationBean.getLocalizedObservationDataSchema(
-                                observationBean.getObservationDataSchema(organizationId, obs.getOrganismId()),
-                                httpServletRequest,
-                                locale
-                        )
+                    observationBean.getLocalizedObservationDataSchema(
+                        observationBean.getObservationDataSchema(organizationId, obs.getOrganismId()),
+                        httpServletRequest,
+                        locale
+                    )
                 );
             } catch (IOException e) {
                 LOGGER.error("Exception when getting localized observation data schema for observation " + obs.getObservationId(), e);
@@ -272,16 +272,16 @@ public class ObservationService {
     @Produces("text/csv;charset=UTF-8")
     @TypeHint(ObservationListItem.class)
     public Response getFilteredObservationListItemsAsCSV(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
-            @QueryParam("pestId") Integer pestId,
-            @QueryParam("cropId") Integer cropId,
-            @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
-            @QueryParam("from") String fromStr,
-            @QueryParam("to") String toStr,
-            @QueryParam("userUUID") String userUUID,
-            @QueryParam("locale") String localeStr,
-            @QueryParam("isPositive") Boolean isPositive
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
+        @QueryParam("pestId") Integer pestId,
+        @QueryParam("cropId") Integer cropId,
+        @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
+        @QueryParam("from") String fromStr,
+        @QueryParam("to") String toStr,
+        @QueryParam("userUUID") String userUUID,
+        @QueryParam("locale") String localeStr,
+        @QueryParam("isPositive") Boolean isPositive
     ) {
         List<ObservationListItem> observations = this.getFilteredObservationListItems(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive);
         Collections.sort(observations);
@@ -295,12 +295,12 @@ public class ObservationService {
                 c = ((Point) geometries.get(0)).getCoordinate();
             }
             retVal += "\n" + obs.getObservationId()
-                    + ";" + obs.getOrganismName()
-                    + ";" + obs.getCropOrganismName()
-                    + ";" + obs.getTimeOfObservation()
-                    + ";" + (c != null ? c.getY() + "," + c.getX() : "")
-                    + ";" + obs.getObservationHeading()
-                    + ";" + obs.getObservationData();
+                + ";" + obs.getOrganismName()
+                + ";" + obs.getCropOrganismName()
+                + ";" + obs.getTimeOfObservation()
+                + ";" + (c != null ? c.getY() + "," + c.getX() : "")
+                + ";" + obs.getObservationHeading()
+                + ";" + obs.getObservationData();
         }
         return Response.ok().entity(retVal).build();
     }
@@ -316,14 +316,14 @@ public class ObservationService {
      * @return Observation objects for which the user is authorized to observe with properties relevant for lists
      */
     private List<Observation> getFilteredObservationsFromBackend(
-            Integer organizationId,
-            Integer observationTimeSeriesId,
-            Integer pestId,
-            Integer cropId,
-            List<Integer> cropCategoryId,
-            String fromStr,
-            String toStr,
-            Boolean isPositive) {
+        Integer organizationId,
+        Integer observationTimeSeriesId,
+        Integer pestId,
+        Integer cropId,
+        List<Integer> cropCategoryId,
+        String fromStr,
+        String toStr,
+        Boolean isPositive) {
         SimpleDateFormat format = new SimpleDateFormat(Globals.defaultDateFormat);
         //TODO Set correct timeZone!!!
         Date from = null;
@@ -336,14 +336,14 @@ public class ObservationService {
         }
 
         return observationBean.getFilteredObservations(
-                organizationId,
-                observationTimeSeriesId,
-                pestId,
-                cropId,
-                cropCategoryId,
-                from,
-                to,
-                isPositive
+            organizationId,
+            observationTimeSeriesId,
+            pestId,
+            cropId,
+            cropCategoryId,
+            from,
+            to,
+            isPositive
         );
 
     }
@@ -461,14 +461,14 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(GeoJSON.class)
     public Response getFilteredObservationsAsGeoJSON(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
-            @QueryParam("pestId") Integer pestId,
-            @QueryParam("cropId") Integer cropId,
-            @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
-            @QueryParam("from") String fromStr,
-            @QueryParam("to") String toStr,
-            @QueryParam("isPositive") Boolean isPositive
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
+        @QueryParam("pestId") Integer pestId,
+        @QueryParam("cropId") Integer cropId,
+        @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
+        @QueryParam("from") String fromStr,
+        @QueryParam("to") String toStr,
+        @QueryParam("isPositive") Boolean isPositive
 
     ) {
         SimpleDateFormat format = new SimpleDateFormat(Globals.defaultDateFormat);
@@ -483,14 +483,14 @@ public class ObservationService {
         }
 
         List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(
-                organizationId,
-                observationTimeSeriesId,
-                pestId,
-                cropId,
-                cropCategoryId,
-                fromStr,
-                toStr,
-                isPositive
+            organizationId,
+            observationTimeSeriesId,
+            pestId,
+            cropId,
+            cropCategoryId,
+            fromStr,
+            toStr,
+            isPositive
         );
 
         GISEntityUtil gisUtil = new GISEntityUtil();
@@ -555,7 +555,7 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(Observation[].class)
     public Response getObservationsForUser(
-            @QueryParam("observationIds") String observationIds
+        @QueryParam("observationIds") String observationIds
     ) {
         LOGGER.info("getObservationsForUser for observationIds={}", observationIds);
         try {
@@ -566,14 +566,14 @@ public class ObservationService {
                 LOGGER.info("Found {} observations for user {}", allObs.size(), user.getUserId());
                 if (observationIds != null) {
                     Set<Integer> observationIdSet = Arrays.asList(observationIds.split(",")).stream()
-                            .map(s -> Integer.valueOf(s))
-                            .collect(Collectors.toSet());
+                        .map(s -> Integer.valueOf(s))
+                        .collect(Collectors.toSet());
                     return Response.ok().entity(
-                                    allObs.stream()
-                                            .filter(obs -> observationIdSet.contains(obs.getObservationId()))
-                                            .collect(Collectors.toList())
-                            )
-                            .build();
+                            allObs.stream()
+                                .filter(obs -> observationIdSet.contains(obs.getObservationId()))
+                                .collect(Collectors.toList())
+                        )
+                        .build();
                 }
                 return Response.ok().entity(allObs).build();
             } else {
@@ -600,7 +600,7 @@ public class ObservationService {
         VipsLogicUser user = userBean.getUserFromUUID(httpServletRequest);
         if (user != null) {
             return Response.ok().entity(observationBean.getObservationsForUser(user).stream()
-                    .map(obs -> new ObservationSyncInfo(obs)).collect(Collectors.toList())).build();
+                .map(obs -> new ObservationSyncInfo(obs)).collect(Collectors.toList())).build();
         } else {
             return Response.status(Status.UNAUTHORIZED).build();
         }
@@ -618,13 +618,13 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(Observation[].class)
     public Response getBroadcastObservations(
-            @PathParam("organizationId") Integer organizationId,
-            @QueryParam("season") Integer season,
-            @QueryParam("timeOfObservationFrom") String timeOfObservationFrom,
-            @QueryParam("timeOfObservationTo") String timeOfObservationTo
+        @PathParam("organizationId") Integer organizationId,
+        @QueryParam("season") Integer season,
+        @QueryParam("timeOfObservationFrom") String timeOfObservationFrom,
+        @QueryParam("timeOfObservationTo") String timeOfObservationTo
     ) {
         if ((timeOfObservationFrom != null && !timeOfObservationFrom.isEmpty())
-                || (timeOfObservationTo != null && !timeOfObservationTo.isEmpty())) {
+            || (timeOfObservationTo != null && !timeOfObservationTo.isEmpty())) {
             Date from = null;
             Date to = null;
             try {
@@ -656,8 +656,8 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(Observation.class)
     public Response getObservation(
-            @PathParam("observationId") Integer observationId,
-            @QueryParam("userUUID") String userUUID
+        @PathParam("observationId") Integer observationId,
+        @QueryParam("userUUID") String userUUID
     ) {
         // Observation needs to be masked here as well, or does it create trouble for VIPSLogic observation admin?
         Observation o = observationBean.getObservation(observationId);
@@ -686,9 +686,9 @@ public class ObservationService {
                 List<Observation> intermediary = new ArrayList<>();
                 intermediary.add(o);
                 intermediary = this.maskObservations(o.getPolygonService(),
-                        observationBean.getObservationsWithLocations(
-                                observationBean.getObservationsWithGeoInfo(intermediary)
-                        )
+                    observationBean.getObservationsWithLocations(
+                        observationBean.getObservationsWithGeoInfo(intermediary)
+                    )
                 );
                 o = intermediary.get(0);
             }
@@ -709,7 +709,7 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(PolygonService[].class)
     public Response getPolygonServicesForOrganization(
-            @PathParam("organizationId") Integer organizationId
+        @PathParam("organizationId") Integer organizationId
     ) {
         return Response.ok().entity(observationBean.getPolygonServicesForOrganization(organizationId)).build();
     }
@@ -729,10 +729,10 @@ public class ObservationService {
             return Response.status(Response.Status.UNAUTHORIZED).build();
         }
         if (!userBean.authorizeUser(user,
-                VipsLogicRole.OBSERVER,
-                VipsLogicRole.OBSERVATION_AUTHORITY,
-                VipsLogicRole.ORGANIZATION_ADMINISTRATOR,
-                VipsLogicRole.SUPERUSER
+            VipsLogicRole.OBSERVER,
+            VipsLogicRole.OBSERVATION_AUTHORITY,
+            VipsLogicRole.ORGANIZATION_ADMINISTRATOR,
+            VipsLogicRole.SUPERUSER
         )
         ) {
             return Response.status(Response.Status.FORBIDDEN).build();
@@ -762,10 +762,10 @@ public class ObservationService {
                 return Response.status(Response.Status.UNAUTHORIZED).build();
             }
             if (!userBean.authorizeUser(user,
-                    VipsLogicRole.OBSERVER,
-                    VipsLogicRole.OBSERVATION_AUTHORITY,
-                    VipsLogicRole.ORGANIZATION_ADMINISTRATOR,
-                    VipsLogicRole.SUPERUSER
+                VipsLogicRole.OBSERVER,
+                VipsLogicRole.OBSERVATION_AUTHORITY,
+                VipsLogicRole.ORGANIZATION_ADMINISTRATOR,
+                VipsLogicRole.SUPERUSER
             )
             ) {
                 return Response.status(Response.Status.FORBIDDEN).build();
@@ -794,7 +794,7 @@ public class ObservationService {
     public Response getFirstObservation(@PathParam("organismId") Integer organismId) {
         Date firstObsTime = observationBean.getFirstObservationTime(organismId);
         return firstObsTime != null ? Response.ok().entity(firstObsTime).build()
-                : Response.status(404).entity("No observations of organism with id=" + organismId).build();
+            : Response.status(404).entity("No observations of organism with id=" + organismId).build();
     }
 
     /**
@@ -827,15 +827,15 @@ public class ObservationService {
      * @return A list of observations that meets the filter criteria
      */
     private List<Observation> getFilteredObservationsFromBackend(
-            Integer organizationId,
-            Integer observationTimeSeriesId,
-            Integer pestId,
-            Integer cropId,
-            List<Integer> cropCategoryId,
-            String fromStr,
-            String toStr,
-            Boolean isPositive,
-            VipsLogicUser user
+        Integer organizationId,
+        Integer observationTimeSeriesId,
+        Integer pestId,
+        Integer cropId,
+        List<Integer> cropCategoryId,
+        String fromStr,
+        String toStr,
+        Boolean isPositive,
+        VipsLogicUser user
     ) {
         List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, isPositive);
 
@@ -889,7 +889,7 @@ public class ObservationService {
             Map<Integer, Observation> maskedObservations = new HashMap<>();
             registeredPolygonServicesInObservationList.keySet().forEach((pService) -> {
                 this.maskObservations(pService, registeredPolygonServicesInObservationList.get(pService))
-                        .forEach(o -> maskedObservations.put(o.getObservationId(), o));
+                    .forEach(o -> maskedObservations.put(o.getObservationId(), o));
             });
 
             // Adding the rest of the observations (the ones that don't need masking)
@@ -908,19 +908,19 @@ public class ObservationService {
         Client client = ClientBuilder.newClient();
         WebTarget target = client.target(polygonService.getGisSearchUrlTemplate());
         List<ReferencedPoint> points = observations.stream()
-                .filter(obs -> (obs.getGeoinfos() != null && !obs.getGeoinfos().isEmpty()) || obs.getLocation() != null)
-                .map(obs -> {
-                    ReferencedPoint rp = new ReferencedPoint();
-                    rp.setId(String.valueOf(obs.getObservationId()));
-                    if (obs.getGeoinfos() != null) {
-                        rp.setLon(obs.getGeoinfos().get(0).getGisGeom().getCoordinate().x);
-                        rp.setLat(obs.getGeoinfos().get(0).getGisGeom().getCoordinate().y);
-                    } else {
-                        rp.setLon(obs.getLocation().getLongitude());
-                        rp.setLat(obs.getLocation().getLatitude());
-                    }
-                    return rp;
-                }).collect(Collectors.toList());
+            .filter(obs -> (obs.getGeoinfos() != null && !obs.getGeoinfos().isEmpty()) || obs.getLocation() != null)
+            .map(obs -> {
+                ReferencedPoint rp = new ReferencedPoint();
+                rp.setId(String.valueOf(obs.getObservationId()));
+                if (obs.getGeoinfos() != null) {
+                    rp.setLon(obs.getGeoinfos().get(0).getGisGeom().getCoordinate().x);
+                    rp.setLat(obs.getGeoinfos().get(0).getGisGeom().getCoordinate().y);
+                } else {
+                    rp.setLon(obs.getLocation().getLongitude());
+                    rp.setLat(obs.getLocation().getLatitude());
+                }
+                return rp;
+            }).collect(Collectors.toList());
         /*System.out.println("maskobservations - target.request() about to be called");
         ObjectMapper oMapper = new ObjectMapper();
         try {
@@ -929,7 +929,7 @@ public class ObservationService {
             Logger.getLogger(ObservationService.class.getName()).log(Level.SEVERE, null, ex);
         }*/
         PointMappingResponse response = target.request(MediaType.APPLICATION_JSON)
-                .post(Entity.entity(points.toArray(new ReferencedPoint[points.size()]), MediaType.APPLICATION_JSON), PointMappingResponse.class);
+            .post(Entity.entity(points.toArray(new ReferencedPoint[points.size()]), MediaType.APPLICATION_JSON), PointMappingResponse.class);
         // We need to loop through the observations and find corresponding featurecollections and replace those
         Map<Integer, Feature> indexedPolygons = new HashMap<>();
         for (Feature feature : response.getFeatureCollection().getFeatures()) {
@@ -965,7 +965,7 @@ public class ObservationService {
     @Produces("application/json;charset=UTF-8")
     @TypeHint(Observation.class)
     public Response syncObservationFromApp(
-            String observationJson
+        String observationJson
     ) {
         LOGGER.info("In syncObservationFromApp");
 
@@ -1124,15 +1124,15 @@ public class ObservationService {
      */
     private List<Observation> sortObservationsByDateAndId(List<Observation> observations) {
         return observations.stream()
-                .sorted((o1, o2) -> {
-                    int timeCompare = o2.getTimeOfObservation().compareTo(o1.getTimeOfObservation());
-                    if (timeCompare != 0) {
-                        return timeCompare;
-                    } else {
-                        return Integer.compare(o2.getObservationId(), o1.getObservationId());
-                    }
-                })
-                .collect(Collectors.toList());
+            .sorted((o1, o2) -> {
+                int timeCompare = o2.getTimeOfObservation().compareTo(o1.getTimeOfObservation());
+                if (timeCompare != 0) {
+                    return timeCompare;
+                } else {
+                    return Integer.compare(o2.getObservationId(), o1.getObservationId());
+                }
+            })
+            .collect(Collectors.toList());
     }
 
     /**
diff --git a/src/main/java/no/nibio/vips/logic/util/ExcelFileGenerator.java b/src/main/java/no/nibio/vips/logic/util/ExcelFileGenerator.java
index 1e1125d1fc2af4f21f6afdfff1a5a22c25066442..242306b53b1674404bb49a9f6503cc17e18e8cf0 100644
--- a/src/main/java/no/nibio/vips/logic/util/ExcelFileGenerator.java
+++ b/src/main/java/no/nibio/vips/logic/util/ExcelFileGenerator.java
@@ -23,420 +23,419 @@ import java.util.*;
 
 public final class ExcelFileGenerator {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelFileGenerator.class);
-    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-    private static final ObjectMapper objectMapper = new ObjectMapper();
-
-    // TODO Dette må fikses før deploy til prod
-    private static final String VIPSWEB = "https://testvips.nibio.no";
-    private static final String VIPSLOGIC = "https://logic.testvips.nibio.no";
-
-    private enum ColumnIndex {
-        ID(false, 0, 0, "observationId"),
-        DATE(false, 1, 1, "timeOfObservation"),
-        POI_NAME(false, 2, 2, "location"),
-        OBSERVER_NAME(true, null, 3, "observer"),
-        OBSERVATION_TIME_SERIES_LABEL(false, 3, 4, "observationTimeSeriesLabel"),
-        ORGANISM(false, 4, 5, "organism"),
-        CROP_ORGANISM(false, 5, 6, "cropOrganismId"),
-        HEADING(false, 6, 7, "observationHeading"),
-        DESCRIPTION(false, 7, 8, "observationText"),
-        BROADCAST(false, 8, 9, "isBroadcast"),
-        POSITIVE(false, 9, 10, "isPositiveRegistration"),
-        INDEX_DATA(false, 10, 11, null);
-
-        private final boolean isSensitive;
-        private final Integer openIndex;
-        private final Integer adminIndex;
-        private final String rbKey;
-
-        ColumnIndex(boolean isSensitive, Integer openIndex, Integer adminIndex, String rbKey) {
-            this.isSensitive = isSensitive;
-            this.openIndex = openIndex;
-            this.adminIndex = adminIndex;
-            this.rbKey = rbKey;
-        }
-
-        public static List<ColumnIndex> forUser(boolean isAdmin) {
-            if (!isAdmin) {
-                return Arrays.stream(ColumnIndex.values()).filter(columnIndex -> !columnIndex.isSensitive).toList();
-            }
-            return Arrays.stream(ColumnIndex.values()).toList();
-        }
-
-        public String getColumnHeading(ResourceBundle rb) {
-            return rbKey != null && !rbKey.isBlank() ? rb.getString(rbKey) : "";
-        }
-
-        public Integer getIndex(boolean admin) {
-            if (admin) {
-                return adminIndex;
-            }
-            return openIndex;
-        }
-    }
-
-    public static byte[] generateExcel(VipsLogicUser user, ULocale locale, LocalDateTime now, String fromStr, String toStr, List<ObservationListItem> observations) throws IOException {
-        ResourceBundle rb = ResourceBundle.getBundle("no.nibio.vips.logic.i18n.vipslogictexts", locale.toLocale());
-        boolean isAdmin = user != null && (user.isSuperUser() || user.isOrganizationAdmin());
-        LOGGER.info("Create Excel file containing {} observations for {} user", observations.size(), isAdmin ? "admin" : "regular");
-        try (XSSFWorkbook workbook = new XSSFWorkbook();
-             ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-
-            Font font = workbook.createFont();
-            font.setBold(true);
-            CellStyle headerStyle = workbook.createCellStyle();
-            headerStyle.setFont(font);
-
-            // Create main sheet for all observations, with header row
-            Sheet mainSheet = workbook.createSheet(rb.getString("allObservations"));
-            createHeaderRow(isAdmin, mainSheet, headerStyle, rb);
-
-            int mainSheetRowIndex = 1;
-            // Add one row for each observation in list of all observations
-            for (ObservationListItem item : observations) {
-                createItemRow(isAdmin, mainSheet, mainSheetRowIndex++, item, rb);
-            }
-            autoSizeColumns(mainSheet, 0, ColumnIndex.INDEX_DATA.getIndex(isAdmin) - 1);
-
-            // Create meta sheet for information about the download
-            Sheet metaSheet = workbook.createSheet(rb.getString("downloadInfo"));
-            addMetaInfo(metaSheet, user, now, fromStr, toStr, observations, headerStyle, rb);
-
-            // Prepare list of observations for each type of pest
-            Map<Integer, List<ObservationListItem>> pestObservations = getObservationsForEachPest(observations);
-
-            // Create sheets for each individual pest type
-            for (Integer pestId : pestObservations.keySet()) {
-                List<ObservationListItem> observationsForPest = pestObservations.get(pestId);
-                ObservationListItem firstObservationForPest = observationsForPest.get(0);
-                String pestName = firstObservationForPest.getOrganismName();
-                Sheet pestSheet = workbook.createSheet(sanitizeSheetName(pestId, pestName));
-                Row headerRow = createHeaderRow(isAdmin, pestSheet, headerStyle, rb);
-
-                // Add column titles for observation data
-                Map<String, String> dataColumnTitles = getObservationDataColumnTitles(firstObservationForPest.getObservationDataSchema());
-                int pestSheetColIndex = ColumnIndex.INDEX_DATA.getIndex(isAdmin);
-                for (String key : dataColumnTitles.keySet()) {
-                    Cell cell = headerRow.createCell(pestSheetColIndex++);
-                    cell.setCellStyle(headerStyle);
-                    cell.setCellValue(dataColumnTitles.get(key));
-                }
-
-                int pestSheetRowIndex = 1;
-                for (ObservationListItem item : observationsForPest) {
-                    Row row = createItemRow(isAdmin, pestSheet, pestSheetRowIndex++, item, rb);
-
-                    if (item.getObservationData() != null) {
-                        Map<String, Object> observationDataMap = objectMapper.readValue(item.getObservationData(), HashMap.class);
-                        if (observationDataMap != null) {
-                            pestSheetColIndex = ColumnIndex.INDEX_DATA.getIndex(isAdmin);
-                            for (String key : dataColumnTitles.keySet()) {
-                                pestSheetColIndex = addValueToCell(row, pestSheetColIndex, observationDataMap.get(key));
-                            }
-                        }
-                    }
-                }
-                autoSizeColumns(pestSheet, ColumnIndex.ID.getIndex(isAdmin), ColumnIndex.INDEX_DATA.getIndex(isAdmin) + dataColumnTitles.size());
-            }
-
-            workbook.write(out);
-            return out.toByteArray();
-        }
+  private static final Logger LOGGER = LoggerFactory.getLogger(ExcelFileGenerator.class);
+  private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+  private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+  private static final ObjectMapper objectMapper = new ObjectMapper();
+
+  private static final String VIPSWEB = "https://www.vips-landbruk.no";
+  private static final String VIPSLOGIC = "https://logic.vips.nibio.no";
+
+  private enum ColumnIndex {
+    ID(false, 0, 0, "observationId"),
+    DATE(false, 1, 1, "timeOfObservation"),
+    POI_NAME(false, 2, 2, "location"),
+    OBSERVER_NAME(true, null, 3, "observer"),
+    OBSERVATION_TIME_SERIES_LABEL(false, 3, 4, "observationTimeSeriesLabel"),
+    ORGANISM(false, 4, 5, "organism"),
+    CROP_ORGANISM(false, 5, 6, "cropOrganismId"),
+    HEADING(false, 6, 7, "observationHeading"),
+    DESCRIPTION(false, 7, 8, "observationText"),
+    BROADCAST(false, 8, 9, "isBroadcast"),
+    POSITIVE(false, 9, 10, "isPositiveRegistration"),
+    INDEX_DATA(false, 10, 11, null);
+
+    private final boolean isSensitive;
+    private final Integer openIndex;
+    private final Integer adminIndex;
+    private final String rbKey;
+
+    ColumnIndex(boolean isSensitive, Integer openIndex, Integer adminIndex, String rbKey) {
+      this.isSensitive = isSensitive;
+      this.openIndex = openIndex;
+      this.adminIndex = adminIndex;
+      this.rbKey = rbKey;
     }
 
-    /**
-     * Add meta information to given sheet
-     *
-     * @param metaSheet    The sheet in which to add content
-     * @param user         The current user
-     * @param now          The current timestamp
-     * @param fromStr      The start of the period for which we have observations
-     * @param toStr        The end of the period for which we have observations
-     * @param observations The list of observations
-     * @param headerStyle  How to style the title cells
-     * @param rb           Resource bundle with translations
-     */
-    private static void addMetaInfo(Sheet metaSheet, VipsLogicUser user, LocalDateTime now, String fromStr, String toStr, List<ObservationListItem> observations, CellStyle headerStyle, ResourceBundle rb) {
-        Row userRow = metaSheet.createRow(0);
-        Cell downloadedByCell = userRow.createCell(0);
-        downloadedByCell.setCellStyle(headerStyle);
-        downloadedByCell.setCellValue(rb.getString("downloadedBy"));
-        userRow.createCell(1).setCellValue(user != null ? user.getFullName() : rb.getString("unregisteredUser"));
-        Row timeRow = metaSheet.createRow(1);
-        Cell downloadedTimeCell = timeRow.createCell(0);
-        downloadedTimeCell.setCellStyle(headerStyle);
-        downloadedTimeCell.setCellValue(rb.getString("downloadedTime"));
-        timeRow.createCell(1).setCellValue(DATE_TIME_FORMATTER.format(now));
-        Row fromRow = metaSheet.createRow(2);
-        Cell dateFromCell = fromRow.createCell(0);
-        dateFromCell.setCellStyle(headerStyle);
-        dateFromCell.setCellValue(rb.getString("dateStart"));
-        fromRow.createCell(1).setCellValue(fromStr);
-        Row toRow = metaSheet.createRow(3);
-        Cell dateToCell = toRow.createCell(0);
-        dateToCell.setCellStyle(headerStyle);
-        dateToCell.setCellValue(rb.getString("dateEnd"));
-        toRow.createCell(1).setCellValue(toStr);
-        Row countRow = metaSheet.createRow(4);
-        Cell countCell = countRow.createCell(0);
-        countCell.setCellStyle(headerStyle);
-        countCell.setCellValue(rb.getString("observationCount"));
-        countRow.createCell(1).setCellValue(observations.size());
-        autoSizeColumns(metaSheet, 0, 1);
+    public static List<ColumnIndex> forUser(boolean isAdmin) {
+      if (!isAdmin) {
+        return Arrays.stream(ColumnIndex.values()).filter(columnIndex -> !columnIndex.isSensitive).toList();
+      }
+      return Arrays.stream(ColumnIndex.values()).toList();
     }
 
-    /**
-     * Create sheet name without invalid characters and within size limits
-     *
-     * @param pestId   The id of the pest
-     * @param pestName The name of the pest
-     * @return a sanitized string to be used as sheet name
-     */
-    private static String sanitizeSheetName(Integer pestId, String pestName) {
-        if (pestName == null || pestName.isBlank()) {
-            return "Id=" + pestId;
-        }
-        return pestName.replaceAll("[\\[\\]\\*/:?\\\\]", "_").substring(0, Math.min(pestName.length(), 31));
+    public String getColumnHeading(ResourceBundle rb) {
+      return rbKey != null && !rbKey.isBlank() ? rb.getString(rbKey) : "";
     }
 
-
-    /**
-     * Auto-size columns of given sheet, from startIndex to endIndex, to ensure that content fits
-     *
-     * @param sheet      The sheet of which to auto-size columns
-     * @param startIndex The index of the first column to auto-size
-     * @param endIndex   The index of the last column to auto-size
-     */
-    private static void autoSizeColumns(Sheet sheet, int startIndex, int endIndex) {
-        for (int i = startIndex; i <= endIndex; i++) {
-            sheet.autoSizeColumn(i);
-        }
+    public Integer getIndex(boolean admin) {
+      if (admin) {
+        return adminIndex;
+      }
+      return openIndex;
     }
-
-    /**
-     * Create map with data property name as key, and corresponding localized name as value
-     *
-     * @param observationDataSchema The observation data schema which contains localized names and other info
-     * @return result map
-     */
-    private static Map<String, String> getObservationDataColumnTitles(ObservationDataSchema observationDataSchema) throws JsonProcessingException {
-        JsonNode rootNode = objectMapper.readTree(observationDataSchema.getDataSchema());
-        JsonNode propertiesNode = rootNode.path("properties");
-        Map<String, String> resultMap = new HashMap<>();
-        Iterator<Map.Entry<String, JsonNode>> fields = propertiesNode.fields();
-        while (fields.hasNext()) {
-            Map.Entry<String, JsonNode> field = fields.next();
-            String key = field.getKey();
-            String value = field.getValue().path("title").asText();
-            resultMap.put(key, value);
+  }
+
+  public static byte[] generateExcel(VipsLogicUser user, ULocale locale, LocalDateTime now, String fromStr, String toStr, List<ObservationListItem> observations) throws IOException {
+    ResourceBundle rb = ResourceBundle.getBundle("no.nibio.vips.logic.i18n.vipslogictexts", locale.toLocale());
+    boolean isAdmin = user != null && (user.isSuperUser() || user.isOrganizationAdmin());
+    LOGGER.info("Create Excel file containing {} observations for {} user", observations.size(), isAdmin ? "admin" : "regular");
+    try (XSSFWorkbook workbook = new XSSFWorkbook();
+        ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+
+      Font font = workbook.createFont();
+      font.setBold(true);
+      CellStyle headerStyle = workbook.createCellStyle();
+      headerStyle.setFont(font);
+
+      // Create main sheet for all observations, with header row
+      Sheet mainSheet = workbook.createSheet(rb.getString("allObservations"));
+      createHeaderRow(isAdmin, mainSheet, headerStyle, rb);
+
+      int mainSheetRowIndex = 1;
+      // Add one row for each observation in list of all observations
+      for (ObservationListItem item : observations) {
+        createItemRow(isAdmin, mainSheet, mainSheetRowIndex++, item, rb);
+      }
+      autoSizeColumns(mainSheet, 0, ColumnIndex.INDEX_DATA.getIndex(isAdmin) - 1);
+
+      // Create meta sheet for information about the download
+      Sheet metaSheet = workbook.createSheet(rb.getString("downloadInfo"));
+      addMetaInfo(metaSheet, user, now, fromStr, toStr, observations, headerStyle, rb);
+
+      // Prepare list of observations for each type of pest
+      Map<Integer, List<ObservationListItem>> pestObservations = getObservationsForEachPest(observations);
+
+      // Create sheets for each individual pest type
+      for (Integer pestId : pestObservations.keySet()) {
+        List<ObservationListItem> observationsForPest = pestObservations.get(pestId);
+        ObservationListItem firstObservationForPest = observationsForPest.get(0);
+        String pestName = firstObservationForPest.getOrganismName();
+        Sheet pestSheet = workbook.createSheet(sanitizeSheetName(pestId, pestName));
+        Row headerRow = createHeaderRow(isAdmin, pestSheet, headerStyle, rb);
+
+        // Add column titles for observation data
+        Map<String, String> dataColumnTitles = getObservationDataColumnTitles(firstObservationForPest.getObservationDataSchema());
+        int pestSheetColIndex = ColumnIndex.INDEX_DATA.getIndex(isAdmin);
+        for (String key : dataColumnTitles.keySet()) {
+          Cell cell = headerRow.createCell(pestSheetColIndex++);
+          cell.setCellStyle(headerStyle);
+          cell.setCellValue(dataColumnTitles.get(key));
         }
-        return resultMap;
-    }
 
-    /**
-     * Create map with pestId as key, and list of corresponding observations as value
-     *
-     * @param observations The original list of observations
-     * @return result map
-     */
-    private static Map<Integer, List<ObservationListItem>> getObservationsForEachPest(List<ObservationListItem> observations) {
-        Map<Integer, List<ObservationListItem>> pestObservations = new HashMap<>();
-        for (ObservationListItem observation : observations) {
-            Integer pestId = observation.getOrganismId();
-            if (!pestObservations.containsKey(pestId)) {
-                List<ObservationListItem> observationList = new ArrayList<>();
-                observationList.add(observation);
-                pestObservations.put(pestId, observationList);
-            } else {
-                pestObservations.get(pestId).add(observation);
+        int pestSheetRowIndex = 1;
+        for (ObservationListItem item : observationsForPest) {
+          Row row = createItemRow(isAdmin, pestSheet, pestSheetRowIndex++, item, rb);
+
+          if (item.getObservationData() != null) {
+            Map<String, Object> observationDataMap = objectMapper.readValue(item.getObservationData(), HashMap.class);
+            if (observationDataMap != null) {
+              pestSheetColIndex = ColumnIndex.INDEX_DATA.getIndex(isAdmin);
+              for (String key : dataColumnTitles.keySet()) {
+                pestSheetColIndex = addValueToCell(row, pestSheetColIndex, observationDataMap.get(key));
+              }
             }
+          }
         }
-        return pestObservations;
-    }
+        autoSizeColumns(pestSheet, ColumnIndex.ID.getIndex(isAdmin), ColumnIndex.INDEX_DATA.getIndex(isAdmin) + dataColumnTitles.size());
+      }
 
-    /**
-     * Create first row of given sheet, with column titles dependent on user privileges
-     *
-     * @param isAdmin     Whether the user is a logged in admin
-     * @param sheet       The sheet to which a row will be added
-     * @param headerStyle The style to be applied to each cell in the header row
-     * @param rb          A resource bundle enabling localized messages
-     * @return the newly created header row
-     */
-    public static Row createHeaderRow(boolean isAdmin, Sheet sheet, CellStyle headerStyle, ResourceBundle rb) {
-        Row headerRow = sheet.createRow(0);
-        for (ColumnIndex columnIndex : ColumnIndex.forUser(isAdmin)) {
-            Cell cell = headerRow.createCell(columnIndex.getIndex(isAdmin));
-            cell.setCellStyle(headerStyle);
-            cell.setCellValue(columnIndex.getColumnHeading(rb));
-        }
-        return headerRow;
+      workbook.write(out);
+      return out.toByteArray();
     }
-
-    /**
-     * Create row with given index, for given observation list item
-     *
-     * @param isAdmin  Whether the user is a logged in admin
-     * @param sheet    The sheet to which a row will be added
-     * @param rowIndex The index of the row
-     * @param item     The item of which to add data
-     * @return the newly created row
-     */
-    private static Row createItemRow(boolean isAdmin, Sheet sheet, int rowIndex, ObservationListItem item, ResourceBundle rb) throws JsonProcessingException {
-        LocalDate localDateOfObservation = item.getTimeOfObservation().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-        Row row = sheet.createRow(rowIndex);
-        addObservationLink(row, ColumnIndex.ID.getIndex(isAdmin), item.getObservationId());
-        addValueToCell(row, ColumnIndex.DATE.getIndex(isAdmin), localDateOfObservation.format(DATE_FORMATTER));
-
-        if (item.getLocationPointOfInterestId() != null) {
-            Integer poiNameIndex = ColumnIndex.POI_NAME.getIndex(isAdmin);
-            if(isAdmin) {
-                addPoiLink(row, poiNameIndex, item.getLocationPointOfInterestId(), item.getLocationPointOfInterestName());
-            } else {
-                addValueToCell(row, poiNameIndex, item.getLocationPointOfInterestName());
-            }
-        }
-
-        if (isAdmin) {
-            addUserLink(row, ColumnIndex.OBSERVER_NAME.getIndex(isAdmin), item.getObserverId(), item.getObserverName());
-        }
-        if (item.getObservationTimeSeriesId() != null) {
-            addTimeSeriesLink(row, ColumnIndex.OBSERVATION_TIME_SERIES_LABEL.getIndex(isAdmin), item.getObservationTimeSeriesId(), item.getObservationTimeSeriesLabel());
-        }
-        addValueToCell(row, ColumnIndex.ORGANISM.getIndex(isAdmin), item.getOrganismName());
-        addValueToCell(row, ColumnIndex.CROP_ORGANISM.getIndex(isAdmin), item.getCropOrganismName());
-        addValueToCell(row, ColumnIndex.HEADING.getIndex(isAdmin), item.getObservationHeading());
-        addValueToCell(row, ColumnIndex.DESCRIPTION.getIndex(isAdmin), item.getObservationText());
-
-        addValueToCell(row, ColumnIndex.BROADCAST.getIndex(isAdmin), getBooleanStringValue(rb, item.getBroadcastMessage()));
-        addValueToCell(row, ColumnIndex.POSITIVE.getIndex(isAdmin), getBooleanStringValue(rb, item.getIsPositive()));
-        return row;
+  }
+
+  /**
+   * Add meta information to given sheet
+   *
+   * @param metaSheet    The sheet in which to add content
+   * @param user         The current user
+   * @param now          The current timestamp
+   * @param fromStr      The start of the period for which we have observations
+   * @param toStr        The end of the period for which we have observations
+   * @param observations The list of observations
+   * @param headerStyle  How to style the title cells
+   * @param rb           Resource bundle with translations
+   */
+  private static void addMetaInfo(Sheet metaSheet, VipsLogicUser user, LocalDateTime now, String fromStr, String toStr, List<ObservationListItem> observations, CellStyle headerStyle, ResourceBundle rb) {
+    Row userRow = metaSheet.createRow(0);
+    Cell downloadedByCell = userRow.createCell(0);
+    downloadedByCell.setCellStyle(headerStyle);
+    downloadedByCell.setCellValue(rb.getString("downloadedBy"));
+    userRow.createCell(1).setCellValue(user != null ? user.getFullName() : rb.getString("unregisteredUser"));
+    Row timeRow = metaSheet.createRow(1);
+    Cell downloadedTimeCell = timeRow.createCell(0);
+    downloadedTimeCell.setCellStyle(headerStyle);
+    downloadedTimeCell.setCellValue(rb.getString("downloadedTime"));
+    timeRow.createCell(1).setCellValue(DATE_TIME_FORMATTER.format(now));
+    Row fromRow = metaSheet.createRow(2);
+    Cell dateFromCell = fromRow.createCell(0);
+    dateFromCell.setCellStyle(headerStyle);
+    dateFromCell.setCellValue(rb.getString("dateStart"));
+    fromRow.createCell(1).setCellValue(fromStr);
+    Row toRow = metaSheet.createRow(3);
+    Cell dateToCell = toRow.createCell(0);
+    dateToCell.setCellStyle(headerStyle);
+    dateToCell.setCellValue(rb.getString("dateEnd"));
+    toRow.createCell(1).setCellValue(toStr);
+    Row countRow = metaSheet.createRow(4);
+    Cell countCell = countRow.createCell(0);
+    countCell.setCellStyle(headerStyle);
+    countCell.setCellValue(rb.getString("observationCount"));
+    countRow.createCell(1).setCellValue(observations.size());
+    autoSizeColumns(metaSheet, 0, 1);
+  }
+
+  /**
+   * Create sheet name without invalid characters and within size limits
+   *
+   * @param pestId   The id of the pest
+   * @param pestName The name of the pest
+   * @return a sanitized string to be used as sheet name
+   */
+  private static String sanitizeSheetName(Integer pestId, String pestName) {
+    if (pestName == null || pestName.isBlank()) {
+      return "Id=" + pestId;
     }
-
-    /**
-     * Add value to cell
-     *
-     * @param row      The row to which the value should be added
-     * @param colIndex The index of the column to add the value to
-     * @param value    The value
-     * @return The next index value
-     */
-    private static Integer addValueToCell(Row row, Integer colIndex, Object value) {
-        Integer index = colIndex;
-        if (value == null) {
-            row.createCell(index++).setCellValue("");
-        } else if (value instanceof Number) {
-            row.createCell(index++).setCellValue(((Number) value).intValue());
-        } else {
-            try {
-                int intValue = Integer.parseInt(value.toString());
-                row.createCell(index++).setCellValue(intValue);
-            } catch (NumberFormatException e) {
-                row.createCell(index++).setCellValue(value.toString());
-            }
-        }
-        return index;
+    return pestName.replaceAll("[\\[\\]\\*/:?\\\\]", "_").substring(0, Math.min(pestName.length(), 31));
+  }
+
+
+  /**
+   * Auto-size columns of given sheet, from startIndex to endIndex, to ensure that content fits
+   *
+   * @param sheet      The sheet of which to auto-size columns
+   * @param startIndex The index of the first column to auto-size
+   * @param endIndex   The index of the last column to auto-size
+   */
+  private static void autoSizeColumns(Sheet sheet, int startIndex, int endIndex) {
+    for (int i = startIndex; i <= endIndex; i++) {
+      sheet.autoSizeColumn(i);
     }
-
-    /**
-     * Get a localized String representing either true or false
-     *
-     * @param rb    The resource bundle to get the localized string from
-     * @param value Either true or false
-     * @return A localized String
-     */
-    private static String getBooleanStringValue(ResourceBundle rb, Boolean value) {
-        if (value == null) {
-            return null;
-        } else if (value) {
-            return rb.getString("yes");
-        }
-        return rb.getString("no");
+  }
+
+  /**
+   * Create map with data property name as key, and corresponding localized name as value
+   *
+   * @param observationDataSchema The observation data schema which contains localized names and other info
+   * @return result map
+   */
+  private static Map<String, String> getObservationDataColumnTitles(ObservationDataSchema observationDataSchema) throws JsonProcessingException {
+    JsonNode rootNode = objectMapper.readTree(observationDataSchema.getDataSchema());
+    JsonNode propertiesNode = rootNode.path("properties");
+    Map<String, String> resultMap = new HashMap<>();
+    Iterator<Map.Entry<String, JsonNode>> fields = propertiesNode.fields();
+    while (fields.hasNext()) {
+      Map.Entry<String, JsonNode> field = fields.next();
+      String key = field.getKey();
+      String value = field.getValue().path("title").asText();
+      resultMap.put(key, value);
     }
-
-    /**
-     * Add link to observation details in column containing the observation Id
-     *
-     * @param row           A reference to the current row
-     * @param colIndex      The index of the column in which the link should be added
-     * @param observationId The id of the observation
-     */
-    private static void addObservationLink(Row row, Integer colIndex, Integer observationId) {
-        Cell cell = row.createCell(colIndex);
-        cell.setCellValue(observationId);
-
-        Workbook workbook = row.getSheet().getWorkbook();
-        cell.setHyperlink(createHyperlink(workbook, VIPSWEB + "/observations/" + observationId));
-        cell.setCellStyle(hyperlinkCellStyle(workbook));
+    return resultMap;
+  }
+
+  /**
+   * Create map with pestId as key, and list of corresponding observations as value
+   *
+   * @param observations The original list of observations
+   * @return result map
+   */
+  private static Map<Integer, List<ObservationListItem>> getObservationsForEachPest(List<ObservationListItem> observations) {
+    Map<Integer, List<ObservationListItem>> pestObservations = new HashMap<>();
+    for (ObservationListItem observation : observations) {
+      Integer pestId = observation.getOrganismId();
+      if (!pestObservations.containsKey(pestId)) {
+        List<ObservationListItem> observationList = new ArrayList<>();
+        observationList.add(observation);
+        pestObservations.put(pestId, observationList);
+      } else {
+        pestObservations.get(pestId).add(observation);
+      }
     }
-
-    /**
-     * Add link to timeseries details in column with given index
-     *
-     * @param row             A reference to the current row
-     * @param colIndex        The index of the column in which the link should be added
-     * @param timeSeriesId    The id of the timeseries
-     * @param timeSeriesLabel The text which should be displayed in the cell
-     */
-    private static void addTimeSeriesLink(Row row, Integer colIndex, Integer timeSeriesId, String timeSeriesLabel) {
-        Cell cell = row.createCell(colIndex);
-        cell.setCellValue(timeSeriesLabel);
-
-        Workbook workbook = row.getSheet().getWorkbook();
-        cell.setHyperlink(createHyperlink(workbook, VIPSWEB + "/observations/timeseries/" + timeSeriesId));
-        cell.setCellStyle(hyperlinkCellStyle(workbook));
+    return pestObservations;
+  }
+
+  /**
+   * Create first row of given sheet, with column titles dependent on user privileges
+   *
+   * @param isAdmin     Whether the user is a logged in admin
+   * @param sheet       The sheet to which a row will be added
+   * @param headerStyle The style to be applied to each cell in the header row
+   * @param rb          A resource bundle enabling localized messages
+   * @return the newly created header row
+   */
+  public static Row createHeaderRow(boolean isAdmin, Sheet sheet, CellStyle headerStyle, ResourceBundle rb) {
+    Row headerRow = sheet.createRow(0);
+    for (ColumnIndex columnIndex : ColumnIndex.forUser(isAdmin)) {
+      Cell cell = headerRow.createCell(columnIndex.getIndex(isAdmin));
+      cell.setCellStyle(headerStyle);
+      cell.setCellValue(columnIndex.getColumnHeading(rb));
     }
-
-    /**
-     * Add link to poi details in column with given index
-     *
-     * @param row      A reference to the current row
-     * @param colIndex The index of the column in which the link should be added
-     * @param poiId    The id of the poi
-     * @param poiName  The text which should be displayed in the cell
-     */
-    private static void addPoiLink(Row row, Integer colIndex, Integer poiId, String poiName) {
-        Cell cell = row.createCell(colIndex);
-        cell.setCellValue(poiName);
-
-        Workbook workbook = row.getSheet().getWorkbook();
-        cell.setHyperlink(createHyperlink(workbook, VIPSLOGIC + "/weatherStation?pointOfInterestId=" + poiId));
-        cell.setCellStyle(hyperlinkCellStyle(workbook));
+    return headerRow;
+  }
+
+  /**
+   * Create row with given index, for given observation list item
+   *
+   * @param isAdmin  Whether the user is a logged in admin
+   * @param sheet    The sheet to which a row will be added
+   * @param rowIndex The index of the row
+   * @param item     The item of which to add data
+   * @return the newly created row
+   */
+  private static Row createItemRow(boolean isAdmin, Sheet sheet, int rowIndex, ObservationListItem item, ResourceBundle rb) throws JsonProcessingException {
+    LocalDate localDateOfObservation = item.getTimeOfObservation().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+    Row row = sheet.createRow(rowIndex);
+    addObservationLink(row, ColumnIndex.ID.getIndex(isAdmin), item.getObservationId());
+    addValueToCell(row, ColumnIndex.DATE.getIndex(isAdmin), localDateOfObservation.format(DATE_FORMATTER));
+
+    if (item.getLocationPointOfInterestId() != null) {
+      Integer poiNameIndex = ColumnIndex.POI_NAME.getIndex(isAdmin);
+      if(isAdmin) {
+        addPoiLink(row, poiNameIndex, item.getLocationPointOfInterestId(), item.getLocationPointOfInterestName());
+      } else {
+        addValueToCell(row, poiNameIndex, item.getLocationPointOfInterestName());
+      }
     }
 
-    /**
-     * Add link to user details in column with given index
-     *
-     * @param row      A reference to the current row
-     * @param colIndex The index of the column in which the link should be added
-     * @param userId   The id of the user
-     * @param userName The text which should be displayed in the cell
-     */
-    private static void addUserLink(Row row, Integer colIndex, Integer userId, String userName) {
-        Cell cell = row.createCell(colIndex);
-        cell.setCellValue(userName);
-
-        Workbook workbook = row.getSheet().getWorkbook();
-        cell.setHyperlink(createHyperlink(workbook, VIPSLOGIC + "/user?action=viewUser&userId=" + userId));
-        cell.setCellStyle(hyperlinkCellStyle(workbook));
+    if (isAdmin) {
+      addUserLink(row, ColumnIndex.OBSERVER_NAME.getIndex(isAdmin), item.getObserverId(), item.getObserverName());
     }
-
-    private static Hyperlink createHyperlink(Workbook workbook, String url) {
-        CreationHelper creationHelper = workbook.getCreationHelper();
-        Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
-        hyperlink.setAddress(url);
-        return hyperlink;
+    if (item.getObservationTimeSeriesId() != null) {
+      addTimeSeriesLink(row, ColumnIndex.OBSERVATION_TIME_SERIES_LABEL.getIndex(isAdmin), item.getObservationTimeSeriesId(), item.getObservationTimeSeriesLabel());
     }
-
-    private static CellStyle hyperlinkCellStyle(Workbook workbook) {
-        CellStyle hyperlinkStyle = workbook.createCellStyle();
-        Font hlinkFont = workbook.createFont();
-        hlinkFont.setUnderline(Font.U_SINGLE);
-        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
-        hyperlinkStyle.setFont(hlinkFont);
-        return hyperlinkStyle;
+    addValueToCell(row, ColumnIndex.ORGANISM.getIndex(isAdmin), item.getOrganismName());
+    addValueToCell(row, ColumnIndex.CROP_ORGANISM.getIndex(isAdmin), item.getCropOrganismName());
+    addValueToCell(row, ColumnIndex.HEADING.getIndex(isAdmin), item.getObservationHeading());
+    addValueToCell(row, ColumnIndex.DESCRIPTION.getIndex(isAdmin), item.getObservationText());
+
+    addValueToCell(row, ColumnIndex.BROADCAST.getIndex(isAdmin), getBooleanStringValue(rb, item.getBroadcastMessage()));
+    addValueToCell(row, ColumnIndex.POSITIVE.getIndex(isAdmin), getBooleanStringValue(rb, item.getIsPositive()));
+    return row;
+  }
+
+  /**
+   * Add value to cell
+   *
+   * @param row      The row to which the value should be added
+   * @param colIndex The index of the column to add the value to
+   * @param value    The value
+   * @return The next index value
+   */
+  private static Integer addValueToCell(Row row, Integer colIndex, Object value) {
+    Integer index = colIndex;
+    if (value == null) {
+      row.createCell(index++).setCellValue("");
+    } else if (value instanceof Number) {
+      row.createCell(index++).setCellValue(((Number) value).intValue());
+    } else {
+      try {
+        int intValue = Integer.parseInt(value.toString());
+        row.createCell(index++).setCellValue(intValue);
+      } catch (NumberFormatException e) {
+        row.createCell(index++).setCellValue(value.toString());
+      }
+    }
+    return index;
+  }
+
+  /**
+   * Get a localized String representing either true or false
+   *
+   * @param rb    The resource bundle to get the localized string from
+   * @param value Either true or false
+   * @return A localized String
+   */
+  private static String getBooleanStringValue(ResourceBundle rb, Boolean value) {
+    if (value == null) {
+      return null;
+    } else if (value) {
+      return rb.getString("yes");
     }
+    return rb.getString("no");
+  }
+
+  /**
+   * Add link to observation details in column containing the observation Id
+   *
+   * @param row           A reference to the current row
+   * @param colIndex      The index of the column in which the link should be added
+   * @param observationId The id of the observation
+   */
+  private static void addObservationLink(Row row, Integer colIndex, Integer observationId) {
+    Cell cell = row.createCell(colIndex);
+    cell.setCellValue(observationId);
+
+    Workbook workbook = row.getSheet().getWorkbook();
+    cell.setHyperlink(createHyperlink(workbook, VIPSWEB + "/observations/" + observationId));
+    cell.setCellStyle(hyperlinkCellStyle(workbook));
+  }
+
+  /**
+   * Add link to timeseries details in column with given index
+   *
+   * @param row             A reference to the current row
+   * @param colIndex        The index of the column in which the link should be added
+   * @param timeSeriesId    The id of the timeseries
+   * @param timeSeriesLabel The text which should be displayed in the cell
+   */
+  private static void addTimeSeriesLink(Row row, Integer colIndex, Integer timeSeriesId, String timeSeriesLabel) {
+    Cell cell = row.createCell(colIndex);
+    cell.setCellValue(timeSeriesLabel);
+
+    Workbook workbook = row.getSheet().getWorkbook();
+    cell.setHyperlink(createHyperlink(workbook, VIPSWEB + "/observations/timeseries/" + timeSeriesId));
+    cell.setCellStyle(hyperlinkCellStyle(workbook));
+  }
+
+  /**
+   * Add link to poi details in column with given index
+   *
+   * @param row      A reference to the current row
+   * @param colIndex The index of the column in which the link should be added
+   * @param poiId    The id of the poi
+   * @param poiName  The text which should be displayed in the cell
+   */
+  private static void addPoiLink(Row row, Integer colIndex, Integer poiId, String poiName) {
+    Cell cell = row.createCell(colIndex);
+    cell.setCellValue(poiName);
+
+    Workbook workbook = row.getSheet().getWorkbook();
+    cell.setHyperlink(createHyperlink(workbook, VIPSLOGIC + "/weatherStation?pointOfInterestId=" + poiId));
+    cell.setCellStyle(hyperlinkCellStyle(workbook));
+  }
+
+  /**
+   * Add link to user details in column with given index
+   *
+   * @param row      A reference to the current row
+   * @param colIndex The index of the column in which the link should be added
+   * @param userId   The id of the user
+   * @param userName The text which should be displayed in the cell
+   */
+  private static void addUserLink(Row row, Integer colIndex, Integer userId, String userName) {
+    Cell cell = row.createCell(colIndex);
+    cell.setCellValue(userName);
+
+    Workbook workbook = row.getSheet().getWorkbook();
+    cell.setHyperlink(createHyperlink(workbook, VIPSLOGIC + "/user?action=viewUser&userId=" + userId));
+    cell.setCellStyle(hyperlinkCellStyle(workbook));
+  }
+
+  private static Hyperlink createHyperlink(Workbook workbook, String url) {
+    CreationHelper creationHelper = workbook.getCreationHelper();
+    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
+    hyperlink.setAddress(url);
+    return hyperlink;
+  }
+
+  private static CellStyle hyperlinkCellStyle(Workbook workbook) {
+    CellStyle hyperlinkStyle = workbook.createCellStyle();
+    Font hlinkFont = workbook.createFont();
+    hlinkFont.setUnderline(Font.U_SINGLE);
+    hlinkFont.setColor(IndexedColors.BLUE.getIndex());
+    hyperlinkStyle.setFont(hlinkFont);
+    return hyperlinkStyle;
+  }
 
 }
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
index 13230b38ed8e0db010f43a5ee3dd22fdef17d584..a9b44ce07122a6969226b89c41b1e1c4410d5756 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
@@ -1,20 +1,20 @@
 #
- # Copyright (c) 2014 NIBIO <http://www.nibio.no/>. 
- # 
- # This file is part of VIPSLogic.
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero 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 Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program.  If not, see <https://www.gnu.org/licenses/>.
- # 
+# Copyright (c) 2014 NIBIO <http://www.nibio.no/>.
+#
+# This file is part of VIPSLogic.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+#
 isPositiveRegistration=Skadegj\u00f8rer p\u00e5vist
 ALTERNARIA = Alternariamodell
 
diff --git a/src/main/webapp/css/mapModal.css b/src/main/webapp/css/mapModal.css
index 161c578b24d60905e1992d2e42be772c7aec0201..40990f46c4d456ba5612050c98205438245b592d 100644
--- a/src/main/webapp/css/mapModal.css
+++ b/src/main/webapp/css/mapModal.css
@@ -2,19 +2,22 @@
     display: none;
     position: fixed;
     z-index: 1000;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
+    left: 50%;
+    top: 50%;
+    width: 90%;
+    height: 90%;
     overflow: hidden;
     background-color: rgba(0, 0, 0, 0.9);
+    transform: translate(-50%, -50%);
+    border: 2px solid #fff;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+    border-radius: 15px;
 }
 
-.map-modal-content {
-    position: relative;
-    height: 100%;
-    width: 100%;
-    background-color: #fefefe;
+.map-modal.show {
+    display: flex;
+    justify-content: center;
+    align-items: center;
 }
 
 #selected-point-info-panel {
@@ -72,4 +75,4 @@
 #new-point-form {
     z-index: 1200;
     position: absolute;
-}
\ No newline at end of file
+}
diff --git a/src/main/webapp/js/mapModal.js b/src/main/webapp/js/mapModal.js
index 33770f1f148cca2ee05790f2e39c774c3811e150..b5876c773dccebc3f433444db61f575973f23762 100644
--- a/src/main/webapp/js/mapModal.js
+++ b/src/main/webapp/js/mapModal.js
@@ -122,7 +122,7 @@ class MapModal {
     addMapContainer(parentDiv, id) {
         const mapContainer = document.createElement('div');
         mapContainer.id = id;
-        mapContainer.style.height = '100vh';
+        mapContainer.style.height = '100%';
         mapContainer.style.width = '100%';
         mapContainer.style.position = 'relative';
         parentDiv.appendChild(mapContainer);
@@ -288,7 +288,7 @@ class MapModal {
             const containerPoint = this.map.latLngToContainerPoint(latlng);
 
             this.selectedNewPointMarker = circleMarker(latlng, this.styleOfSelectedPointMarker(true)).addTo(this.map);
-            const newPointFormElement = this.addHtmlElementNewPointForm(containerPoint.x + 25, containerPoint.y - 25, latlng.lat, latlng.lng)
+            const newPointFormElement = this.addHtmlElementNewPointForm(containerPoint.x, containerPoint.y, latlng.lat, latlng.lng)
 
             DomEvent.disableClickPropagation(newPointFormElement);
             document.addEventListener('click', this.handleClickOutsidePointForm.bind(this), true);
@@ -390,43 +390,57 @@ class MapModal {
      * @returns {Element}
      */
     addHtmlElementNewPointForm(positionX, positionY, latitude, longitude) {
-        const html = `
-            <div id="new-point-form" class="panel panel-default"  style="top: ${positionY}px; left: ${positionX}px;">
-                <div class="panel-heading">
-                    <h4 class="panel-title">${this.translations.createNewLocation}</h4>
-                    <span id="close-button" style="position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 18px;">&times;</span>
+        const form = document.createElement("div");
+        form.id="new-point-form"
+        form.classList.add("panel");
+        form.classList.add("panel-default");
+
+        // Adjust position so that the form is always displayed within the map
+        const mapWidth = this.mapModalElement.offsetWidth;
+        const mapHeight = this.mapModalElement.offsetHeight;
+        const formWidth = 200; // approximately
+        const formHeight = 400; // approximately
+        if (positionX + formWidth > mapWidth) {
+            positionX = mapWidth - formWidth - 10; // 10px padding from the edge
+        }
+        if (positionY + formHeight > mapHeight) {
+            positionY = mapHeight - formHeight - 10; // 10px padding from the edge
+        }
+        form.style.left = `${positionX}px`;
+        form.style.top = `${positionY}px`;
+
+        form.innerHTML = `
+            <div class="panel-heading">
+                <h4 class="panel-title">${this.translations.createNewLocation}</h4>
+                <span id="close-button" style="position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 18px;">&times;</span>
+            </div>
+            <div class="panel-body">
+                <div class="form-group">
+                    <label for="name">${this.translations.name}:</label>
+                    <input type="text" class="form-control" id="name" name="name">
+                </div>
+                <div class="form-group">
+                    <label for="latitude">${this.translations.latitude}:</label>
+                    <input type="text" class="form-control" id="latitude" name="latitude" value="${latitude.toFixed(this.coordinatePrecision)}">
+                </div>
+                <div class="form-group">
+                    <label for="longitude">${this.translations.longitude}:</label>
+                    <input type="text" class="form-control" id="longitude" name="longitude" value="${longitude.toFixed(this.coordinatePrecision)}">
                 </div>
-                <div class="panel-body">
-                    <div class="form-group">
-                        <label for="name">${this.translations.name}:</label>
-                        <input type="text" class="form-control" id="name" name="name">
-                    </div>
-                    <div class="form-group">
-                        <label for="latitude">${this.translations.latitude}:</label>
-                        <input type="text" class="form-control" id="latitude" name="latitude" value="${latitude.toFixed(this.coordinatePrecision)}">
-                    </div>
-                    <div class="form-group">
-                        <label for="longitude">${this.translations.longitude}:</label>
-                        <input type="text" class="form-control" id="longitude" name="longitude" value="${longitude.toFixed(this.coordinatePrecision)}">
-                    </div>
-                    <div class="form-group">
-                        <label for="poiTypeSelect">${this.translations.type}:</label>
-                        <select class="form-control" id="type" name="type">
-                            <option value="2">${this.typeNameMap[2]}</option>
-                            <option value="3">${this.typeNameMap[3]}</option>
-                            <option value="5">${this.typeNameMap[5]}</option>
-                        </select>
-                    </div>
-                    <div class="form-group text-right">
-                        <button id="submit-button" class="btn btn-primary">${this.translations.submitLocation}</button>
-                    </div>                
+                <div class="form-group">
+                    <label for="poiTypeSelect">${this.translations.type}:</label>
+                    <select class="form-control" id="type" name="type">
+                        <option value="2">${this.typeNameMap[2]}</option>
+                        <option value="3">${this.typeNameMap[3]}</option>
+                        <option value="5">${this.typeNameMap[5]}</option>
+                    </select>
                 </div>
+                <div class="form-group text-right">
+                    <button id="submit-button" class="btn btn-primary">${this.translations.submitLocation}</button>
+                </div>                
             </div>`;
-        const tmpContainer = document.createElement("div");
-        tmpContainer.innerHTML = html;
-        const htmlElement = tmpContainer.querySelector('#new-point-form');
-        this.mapContainerElement.appendChild(htmlElement);
-        return htmlElement;
+        this.mapContainerElement.appendChild(form);
+        return form;
     }
 
     /**
@@ -438,7 +452,9 @@ class MapModal {
      * @param zoomLevel
      */
     openModal(selectedPointOfInterestId, latitude, longitude, zoomLevel) {
-        this.mapModalElement.style.display = 'block';
+        this.mapModalElement.style.display = 'flex';
+        this.mapModalElement.style.justifyContent = 'center';
+        this.mapModalElement.style.alignItems = 'center';
         this.initMap(latitude, longitude, zoomLevel);
         if (selectedPointOfInterestId) {
             this.selectPointById(selectedPointOfInterestId);
@@ -643,4 +659,4 @@ const LegendControl = Control.extend({
 });
 
 // Export the module
-export default MapModal;
\ No newline at end of file
+export default MapModal;
diff --git a/src/main/webapp/map_applications/phytophthora/js/map.js b/src/main/webapp/map_applications/phytophthora/js/map.js
index cbbf27c69596b7afdbbacd7a3404fbc0072138f3..52e59a2ed79de25d5fce8cb5b9b47ee4ea2cff73 100755
--- a/src/main/webapp/map_applications/phytophthora/js/map.js
+++ b/src/main/webapp/map_applications/phytophthora/js/map.js
@@ -36,8 +36,7 @@ var geolocation;
  * Initializes the map with all its layers
  * @returns {undefined}
  */
-async function initMap()
-{
+async function initMap() {
     var features = new ol.Collection();
 
     // Icon styling for the observations layer
@@ -45,52 +44,52 @@ async function initMap()
     var styles = {
         // Bøk = rød
         'fagus sylvatica': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [255, 0, 0, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
-            })],
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [255, 0, 0, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
+            })
+        })],
         // Gråor = dyp oransje
         'alnus incana': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [239, 133, 19, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
-            })],
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [239, 133, 19, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
+            })
+        })],
         // Eik = gul
         'quercus': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [239, 236, 19, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
-            })],
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [239, 236, 19, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
+            })
+        })],
         // Lønn = grønn
         'acer': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [0, 255, 0, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
-            })],
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [0, 255, 0, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
+            })
+        })],
         // Svartor = grågrønn
-        'svartor': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [122, 175, 131, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
-            })],
+        'alnus glutinosa': [new ol.style.Style({
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [122, 175, 131, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
+            })
+        })],
         // Planteriket = blå 
         'plantae': [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [0, 0, 255, 1]}),
-                    stroke: new ol.style.Stroke({width: 1, color: [0, 0, 0, 1]}),
-                    radius: iconRadius
-                })
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [0, 0, 255, 1] }),
+                stroke: new ol.style.Stroke({ width: 1, color: [0, 0, 0, 1] }),
+                radius: iconRadius
             })
+        })
         ]
     };
 
@@ -102,24 +101,21 @@ async function initMap()
         style: function (feature, resolution) {
             // Site that has been cleared is all black
             var observationData = JSON.parse(feature.get("observationData"));
-           
+
             var retVal = null;
-            if (feature.get("cropOrganism") != null && feature.get("cropOrganism")["latinName"] != null)
-            {
+            if (feature.get("cropOrganism") != null && feature.get("cropOrganism")["latinName"] != null) {
                 retVal = styles[feature.get("cropOrganism")["latinName"].toLowerCase()];
-            } else
-            {
+            } else {
                 retVal = styles["plantae"];
             }
             //console.info(retVal[0].getImage().getStroke().getWidth());
             // If symptom has been registered, mark with inner black dot
-            if (observationData["symptom"] != "Ikke symptom" && observationData["symptom"] != "Irrelevant")
-            {
+            if (observationData["symptom"] != "Ikke symptom" && observationData["symptom"] != "Irrelevant") {
                 retVal = [
                     new ol.style.Style({
                         image: new ol.style.Circle({
-                            fill: new ol.style.Fill({color: [0, 0, 0, 1]}),
-                            stroke: new ol.style.Stroke({width: 8, color: retVal[0].getImage().getFill().getColor()}),
+                            fill: new ol.style.Fill({ color: [0, 0, 0, 1] }),
+                            stroke: new ol.style.Stroke({ width: 8, color: retVal[0].getImage().getFill().getColor() }),
                             radius: iconRadius
                         })
                     })
@@ -136,12 +132,12 @@ async function initMap()
             features: new ol.Collection()
         }),
         style: [new ol.style.Style({
-                image: new ol.style.Circle({
-                    fill: new ol.style.Fill({color: [255, 255, 255, 1]}),
-                    stroke: new ol.style.Stroke({color: [0, 0, 0, 1], width: 3, lineDash: [2, 2]}),
-                    radius: 10
-                })
-            })]
+            image: new ol.style.Circle({
+                fill: new ol.style.Fill({ color: [255, 255, 255, 1] }),
+                stroke: new ol.style.Stroke({ color: [0, 0, 0, 1], width: 3, lineDash: [2, 2] }),
+                radius: 10
+            })
+        })]
 
     });
 
@@ -157,15 +153,15 @@ async function initMap()
         });
 
         var topo =
-                new ol.layer.Tile({
-                    opacity: 1,
-                    source: new ol.source.WMTS(/** @type {!olx.source.WMTSOptions} */ (options))
-                });
-            
-        
+            new ol.layer.Tile({
+                opacity: 1,
+                source: new ol.source.WMTS(/** @type {!olx.source.WMTSOptions} */(options))
+            });
+
+
         map = new ol.Map({
             target: 'map',
-            controls: ol.control.defaults({attribution: false}), // Hide the attribution
+            controls: ol.control.defaults({ attribution: false }), // Hide the attribution
             layers: [
                 topo,
                 featureOverlay,
@@ -186,19 +182,19 @@ async function initMap()
         });
         var positionFeature = new ol.Feature();
         positionFeature.setStyle(
-                new ol.style.Style({
-                    image: new ol.style.Circle({
-                        radius: 6,
-                        fill: new ol.style.Fill({
-                            color: '#3399CC',
-                        }),
-                        stroke: new ol.style.Stroke({
-                            color: '#fff',
-                            width: 2,
-                        }),
+            new ol.style.Style({
+                image: new ol.style.Circle({
+                    radius: 6,
+                    fill: new ol.style.Fill({
+                        color: '#3399CC',
                     }),
-                })
-                );
+                    stroke: new ol.style.Stroke({
+                        color: '#fff',
+                        width: 2,
+                    }),
+                }),
+            })
+        );
 
         geolocation.on('change:position', function () {
             var coordinates = geolocation.getPosition();
@@ -223,9 +219,9 @@ async function initMap()
         map.on('click', function (evt) {
             //features = []
             var feature = map.forEachFeatureAtPixel(
-                    evt.pixel, function (ft, l) {
-                        return ft;
-                    }
+                evt.pixel, function (ft, l) {
+                    return ft;
+                }
             );
 
             var vectorSource = newFeatureOverlay.getSource();
@@ -237,8 +233,7 @@ async function initMap()
                 var fakeFeature = createFeature(feature.getGeometry().getCoordinates());
                 vectorSource.addFeature(fakeFeature);
                 displayFeature(feature);
-            } else if (registration)
-            {
+            } else if (registration) {
                 var newFeature = createFeature(map.getCoordinateFromPixel(evt.pixel));
                 vectorSource.addFeature(newFeature);
                 editFeature(newFeature.getId());
@@ -251,10 +246,8 @@ async function initMap()
 
 let openLayersDefaultStyle = undefined;
 
-function getOpenLayersDefaultStyle()
-{
-    if (openLayersDefaultStyle == undefined)
-    {
+function getOpenLayersDefaultStyle() {
+    if (openLayersDefaultStyle == undefined) {
         var fill = new ol.style.Fill({
             color: 'rgba(255,255,255,0.4)'
         });
@@ -284,8 +277,7 @@ function getOpenLayersDefaultStyle()
  * @param {type} fromSeason
  * @returns {undefined}
  */
-function getAndRenderObservations(fromSeason)
-{
+function getAndRenderObservations(fromSeason) {
     //console.info("getAndRenderObservations(" + season + ")");
     $.getJSON("/rest/observation/filter/1/geoJSON?from=" + fromSeason + "-01-01&pestId=" + phytophthora.organismId, function (geoData) {
         //console.info(geoData)
@@ -308,66 +300,58 @@ function getAndRenderObservations(fromSeason)
  *  @param {type} countyNo
  * @returns {undefined}
  */
-function getAndRenderObservationsForReport(fromSeason, countyNo = "-1")
-{
+function getAndRenderObservationsForReport(fromSeason, countyNo = "-1") {
     //console.info("getAndRenderObservations(" + season + ")");
     $.getJSON("/rest/observation/filter/1/geoJSON?from=" + fromSeason + "-01-01&pestId=" + phytophthora.organismId, function (geoData) {
         //console.info(geoData)
         // Filter by county
         $.getJSON("/corsproxy/https://ws.geonorge.no/kommuneinfo/v1/fylker/" + countyNo + "/omrade")
-                .always(function (serviceResponse) {
-                    //console.info(geoData);
-                    //console.info(serviceResponse);
-
-                    if (parseInt(countyNo) > 0)
-                    {
-                        var filteredFeatures = [];
-                        for (var i = 0; i < geoData.features.length; i++)
-                        {
-                            var featureToBeFiltered = geoData.features[i];
-                            coordinate = proj4("EPSG:4326", "EPSG:4258", [featureToBeFiltered.geometry.coordinates[0], featureToBeFiltered.geometry.coordinates[1]]);
-                            // For some weird reason, d3 returns NOT contains in our case
-                            if (!d3.geoContains(serviceResponse.omrade, coordinate))
-                            {
-                                //console.info(featureToBeFiltered);
-                                filteredFeatures.push(featureToBeFiltered);
-                            }
+            .always(function (serviceResponse) {
+                //console.info(geoData);
+                //console.info(serviceResponse);
+
+                if (parseInt(countyNo) > 0) {
+                    var filteredFeatures = [];
+                    for (var i = 0; i < geoData.features.length; i++) {
+                        var featureToBeFiltered = geoData.features[i];
+                        coordinate = proj4("EPSG:4326", "EPSG:4258", [featureToBeFiltered.geometry.coordinates[0], featureToBeFiltered.geometry.coordinates[1]]);
+                        // For some weird reason, d3 returns NOT contains in our case
+                        if (!d3.geoContains(serviceResponse.omrade, coordinate)) {
                             //console.info(featureToBeFiltered);
+                            filteredFeatures.push(featureToBeFiltered);
                         }
-                        //console.info(filteredFeatures);
-                        geoData.features = filteredFeatures;
+                        //console.info(featureToBeFiltered);
                     }
+                    //console.info(filteredFeatures);
+                    geoData.features = filteredFeatures;
+                }
 
-                    var format = new ol.format.GeoJSON();
+                var format = new ol.format.GeoJSON();
 
-                    var drawnfeatures = format.readFeatures(geoData, {
-                        //dataProjection: "EPSG:32633",
-                        dataProjection: "EPSG:4326",
-                        featureProjection: map.getView().getProjection().getCode()
-                    });
-                    featureOverlay.getSource().clear();
-                    featureOverlay.getSource().addFeatures(drawnfeatures);
-                }
-                );
+                var drawnfeatures = format.readFeatures(geoData, {
+                    //dataProjection: "EPSG:32633",
+                    dataProjection: "EPSG:4326",
+                    featureProjection: map.getView().getProjection().getCode()
+                });
+                featureOverlay.getSource().clear();
+                featureOverlay.getSource().addFeatures(drawnfeatures);
+            }
+            );
     });
 }
 
-function toggleRegistration(theButton)
-{
-    if (registration)
-    {
+function toggleRegistration(theButton) {
+    if (registration) {
         theButton.title = "Registrering er AV";
         theButton.style.color = "white";
-    } else
-    {
+    } else {
         theButton.title = "Registrering er PÅ";
         theButton.style.color = "red";
     }
     registration = !registration;
 }
 
-function toggleTracking(theButton)
-{
+function toggleTracking(theButton) {
     geolocation.setTracking(!geolocation.getTracking());
     theButton.style.backgroundColor = geolocation.getTracking() ? "green" : "rgba(0,60,136,.5)";
     theButton.title = geolocation.getTracking() ? "Vis min posisjon er PÅ" : "Vis min posisjon er AV";
@@ -378,10 +362,8 @@ function toggleTracking(theButton)
  * @param {type} coordinate
  * @returns {createFeature.newFeature|ol.Feature}
  */
-var createFeature = function (coordinate)
-{
-    if (coordinate.length == 2)
-    {
+var createFeature = function (coordinate) {
+    if (coordinate.length == 2) {
         coordinate = [coordinate[0], coordinate[1], 0];
     }
     var point = new ol.geom.Point(coordinate);
@@ -401,8 +383,7 @@ var createFeature = function (coordinate)
     return newFeature;
 }
 
-var displayFeature = function (feature)
-{
+var displayFeature = function (feature) {
     var featureForm = document.getElementById("featureForm");
 
     var observationData = JSON.parse(feature.get("observationData"));
@@ -440,8 +421,7 @@ var forekomsttypeLatinskeNavn = [
 var forekomsttyper = [];
 var phytophthora = {};
 
-function initForekomsttyper()
-{
+function initForekomsttyper() {
     $.getJSON("/rest/organism/search/latinnames?keywords=" + forekomsttypeLatinskeNavn.join(","), function (data) {
         forekomsttyper = data;
     });
@@ -449,70 +429,65 @@ function initForekomsttyper()
 
 function initPhytophthora() {
     $.getJSON("/rest/organism/search/latinnames?keywords=Phytophthora sp", function (data) {
-        if (data.length == 1)
-        {
+        if (data.length == 1) {
             phytophthora = data[0];
             initMap();
         }
     });
 }
 
-var getCropOrganism = function (organismId)
-{
-    for (var i = 0; i < forekomsttyper.length; i++)
-    {
-        if (forekomsttyper[i].organismId == organismId)
-        {
+var getCropOrganism = function (organismId) {
+    for (var i = 0; i < forekomsttyper.length; i++) {
+        if (forekomsttyper[i].organismId == organismId) {
             return forekomsttyper[i];
         }
     }
 }
 
 
-var symptoms = ["Flekker", "Glisne kroner","Oppsprekking","Død","Andre symptom","Andre skader","Ikke symptom","Irrelevant"];
+var symptoms = ["Flekker", "Glisne kroner", "Oppsprekking", "Død", "Andre symptom", "Andre skader", "Ikke symptom", "Irrelevant"];
 var funns = ["[Ukjent]", "Phytophthora gonapodyides", "Phytophthora lacustris", "Phytophthora plurivora", "Phytophthora cambivora", "Phytophthora cactorum", "Phytophthora sp"]
-var provetypes = ["[Ikke prøve]","Jord","Vev","Vann","Blad","Bait"];
+var provetypes = ["[Ikke prøve]", "Jord", "Vev", "Vann", "Blad", "Bait"];
 
 
-var editFeature = function (featureId)
-{
+var editFeature = function (featureId) {
     var feature = featureId > 0 ? featureOverlay.getSource().getFeatureById(featureId)
-            : newFeatureOverlay.getSource().getFeatureById(featureId);
+        : newFeatureOverlay.getSource().getFeatureById(featureId);
     var observationData = JSON.parse(feature.get("observationData"));
     var timeOfObservation = new moment(feature.get("timeOfObservation"));
     var featureForm = document.getElementById("featureForm");
     var html =
-            '<button type="button" onclick="unFocusForm()" title="Avbryt">X</button>' +
-            (featureId > 0 ? '<button type="button" onclick="deleteFeature(' + featureId + ')">Delete</button>' : '') +
-            '<h3>' + (featureId > 0 ? "R" : "Ny r") + 'egistrering</h3>' +
-            '<table>' +
-            '<tr><td>Plante</td><td>' +
-            generateCropSelect("forekomsttype", forekomsttyper, feature.get("cropOrganism")["organismId"]) +
-            '</td></tr>' +
-            '<tr><td>Plante spes.</td><td>' +
-            '<input type="text" id="plantespes" name="plantespes" size="15" value="' + (observationData["plantespes"] != null ? observationData["plantespes"] : "") + '"/></td></tr>' +
-            '<tr><td>Symptom</td><td>' +
-            generateSelect("symptom", symptoms, observationData["symptom"]) +
-            '</td></tr>' +
-            '<tr><td>Sym spes.</td><td>' +
-            '<input type="text" id="symspes" name="symspes" size="15" value="' + (observationData["symspes"] != null ? observationData["symspes"] : "") + '"/></td></tr>' +
-           
-            '<tr><td>Prøvetype</td><td>' +
-            generateSelect("provetype", provetypes, observationData["provetype"]) +
-            '</td></tr>' +
-            '<tr><td>Prøvenummer</td><td>' +
-            '<input type="text" id="provenummer" name="provenummer" size="15" value="' + (observationData["provenummer"] != null ? observationData["provenummer"] : "") + '"/></td></tr>' +
-            '<tr><td>Funn</td><td>' +
-            generateSelect("funn", funns, observationData["funn"]) +
-            '</td></tr>' +
-            '<tr><td>Mer info</td><td>' +
-            '<textarea id="beskrivelse" name="beskrivelse">' + (feature.get("observationText") != null ? feature.get("observationText") : "") + '</textarea>' +
-            '</td></tr>' +
-            '<tr><td>Dato</td><td>' +
-            '<input type="text" id="dato" name="dato" size="10" value="' + timeOfObservation.format("DD.MM.YYYY") + '"/></td></tr>' +
-            '<tr><td></td><td>' +
-            '<input type="submit" value="Lagre" onclick="storeFeature(' + feature.getId() + ');"/></td></tr>' +
-            '</table>';
+        '<button type="button" onclick="unFocusForm()" title="Avbryt">X</button>' +
+        (featureId > 0 ? '<button type="button" onclick="deleteFeature(' + featureId + ')">Delete</button>' : '') +
+        '<h3>' + (featureId > 0 ? "R" : "Ny r") + 'egistrering</h3>' +
+        '<table>' +
+        '<tr><td>Plante</td><td>' +
+        generateCropSelect("forekomsttype", forekomsttyper, feature.get("cropOrganism")["organismId"]) +
+        '</td></tr>' +
+        '<tr><td>Plante spes.</td><td>' +
+        '<input type="text" id="plantespes" name="plantespes" size="15" value="' + (observationData["plantespes"] != null ? observationData["plantespes"] : "") + '"/></td></tr>' +
+        '<tr><td>Symptom</td><td>' +
+        generateSelect("symptom", symptoms, observationData["symptom"]) +
+        '</td></tr>' +
+        '<tr><td>Sym spes.</td><td>' +
+        '<input type="text" id="symspes" name="symspes" size="15" value="' + (observationData["symspes"] != null ? observationData["symspes"] : "") + '"/></td></tr>' +
+
+        '<tr><td>Prøvetype</td><td>' +
+        generateSelect("provetype", provetypes, observationData["provetype"]) +
+        '</td></tr>' +
+        '<tr><td>Prøvenummer</td><td>' +
+        '<input type="text" id="provenummer" name="provenummer" size="15" value="' + (observationData["provenummer"] != null ? observationData["provenummer"] : "") + '"/></td></tr>' +
+        '<tr><td>Funn</td><td>' +
+        generateSelect("funn", funns, observationData["funn"]) +
+        '</td></tr>' +
+        '<tr><td>Mer info</td><td>' +
+        '<textarea id="beskrivelse" name="beskrivelse">' + (feature.get("observationText") != null ? feature.get("observationText") : "") + '</textarea>' +
+        '</td></tr>' +
+        '<tr><td>Dato</td><td>' +
+        '<input type="text" id="dato" name="dato" size="10" value="' + timeOfObservation.format("DD.MM.YYYY") + '"/></td></tr>' +
+        '<tr><td></td><td>' +
+        '<input type="submit" value="Lagre" onclick="storeFeature(' + feature.getId() + ');"/></td></tr>' +
+        '</table>';
 
 
     featureForm.innerHTML = html;
@@ -520,10 +495,9 @@ var editFeature = function (featureId)
     //console.info(feature);
 };
 
-var storeFeature = function (featureId)
-{
+var storeFeature = function (featureId) {
     var feature = featureId > 0 ? featureOverlay.getSource().getFeatureById(featureId)
-            : newFeatureOverlay.getSource().getFeatureById(featureId);
+        : newFeatureOverlay.getSource().getFeatureById(featureId);
 
     // Store, clear newFeature layer
     // Need to add feature as payload
@@ -541,8 +515,7 @@ var storeFeature = function (featureId)
     var observationText = document.getElementById("beskrivelse").value;
     var observationHeading = "Registrering av phytophthora";
     var timeOfObservation = moment(document.getElementById("dato").value + "+0200", "DD.MM.YYYYZ");
-    if (timeOfObservation.year() < 2000)
-    {
+    if (timeOfObservation.year() < 2000) {
         alert("Feil dato (før år 2000). Datoformat er DD.MM.ÅÅÅÅ");
         return;
     }
@@ -585,22 +558,18 @@ var storeFeature = function (featureId)
             // If storing an existing feature, remove the one
             // that was there before storing, since the returned
             // one has a new gisId (featureId)
-            if (featureId > 0)
-            {
+            if (featureId > 0) {
                 featureOverlay.getSource().removeFeature(feature);
             }
             featureOverlay.getSource().addFeatures(drawnfeatures);
             unFocusForm();
         },
         error: function (jqXHR, textStatus, errorThrown) {
-            if (jqXHR.status == 401)
-            {
-                if (confirm("Kan ikke lagre fordi du er logget ut av applikasjonen. Klikk OK for å logge inn."))
-                {
+            if (jqXHR.status == 401) {
+                if (confirm("Kan ikke lagre fordi du er logget ut av applikasjonen. Klikk OK for å logge inn.")) {
                     window.location.reload();
                 }
-            } else
-            {
+            } else {
                 alert("Beklager, en feil oppsto. Status = " + jqXHR.status + ", eventuell feilmelding: " + textStatus);
             }
         }
@@ -614,10 +583,8 @@ var storeFeature = function (featureId)
  * @param {type} featureId
  * @returns {undefined}
  */
-var deleteFeature = function (featureId)
-{
-    if (!confirm("Er du sikker på at du vil slette?"))
-    {
+var deleteFeature = function (featureId) {
+    if (!confirm("Er du sikker på at du vil slette?")) {
         return;
     }
 
@@ -631,51 +598,41 @@ var deleteFeature = function (featureId)
             // If storing an existing feature, remove the one
             // that was there before storing, since the returned
             // one has a new gisId (featureId)
-            if (featureId > 0)
-            {
+            if (featureId > 0) {
                 featureOverlay.getSource().removeFeature(feature);
             }
             unFocusForm();
         },
         error: function (jqXHR, textStatus, errorThrown) {
-            if (jqXHR.status == 401)
-            {
-                if (confirm("Kan ikke slette fordi du er logget ut av applikasjonen. Klikk OK for å logge inn."))
-                {
+            if (jqXHR.status == 401) {
+                if (confirm("Kan ikke slette fordi du er logget ut av applikasjonen. Klikk OK for å logge inn.")) {
                     window.location.reload();
                 }
-            } else
-            {
+            } else {
                 alert("Beklager, en feil oppsto. Status = " + jqXHR.status + ", eventuell feilmelding: " + textStatus);
             }
         }
     });
 }
 
-var generateSelect = function (selectName, options, preselect)
-{
+var generateSelect = function (selectName, options, preselect) {
     var retVal = '<select id="' + selectName + '" name="' + selectName + '">';
-    for (var i = 0; i < options.length; i++)
-    {
+    for (var i = 0; i < options.length; i++) {
         retVal += '<option value="' + options[i] + '"' + (options[i] == preselect ? " selected=\"selected\"" : "") + '">' + options[i] + '</option>';
     }
     retVal += '</select>';
     return retVal;
 }
 
-var generateCropSelect = function (selectName, cropOrganisms, preselect)
-{
+var generateCropSelect = function (selectName, cropOrganisms, preselect) {
     var retVal = '<select id="' + selectName + '" name="' + selectName + '">';
-    for (var c = 0; c < forekomsttypeLatinskeNavn.length; c++)
-    {
+    for (var c = 0; c < forekomsttypeLatinskeNavn.length; c++) {
         currentLatinName = forekomsttypeLatinskeNavn[c];
-        for (var i = 0; i < cropOrganisms.length; i++)
-        {
-            if (cropOrganisms[i].latinName == currentLatinName)
-            {
+        for (var i = 0; i < cropOrganisms.length; i++) {
+            if (cropOrganisms[i].latinName == currentLatinName) {
                 retVal += '<option value="' + cropOrganisms[i].organismId + '"' + (cropOrganisms[i].organismId == preselect ? " selected=\"selected\"" : "") + '">' +
-                        (currentLatinName == "Plantae" ? "Annet" : getLocalizedOrganismName(cropOrganisms[i], hardcodedLanguage))
-                        + '</option>';
+                    (currentLatinName == "Plantae" ? "Annet" : getLocalizedOrganismName(cropOrganisms[i], hardcodedLanguage))
+                    + '</option>';
             }
         }
     }
@@ -683,22 +640,19 @@ var generateCropSelect = function (selectName, cropOrganisms, preselect)
     return retVal;
 }
 
-var focusForm = function ()
-{
+var focusForm = function () {
     var featureForm = document.getElementById("featureForm");
     featureForm.style.display = "block";
 }
 
-var unFocusForm = function ()
-{
+var unFocusForm = function () {
     var featureForm = document.getElementById("featureForm");
     featureForm.style.display = "none";
     // Also remove feature (if one) on the New feature overlay
     newFeatureOverlay.getSource().clear();
 }
 
-var navigateTo = function (center)
-{
+var navigateTo = function (center) {
     var centerPosition = ol.proj.transform(center, 'EPSG:4326', 'EPSG:3857');
     view = new ol.View({
         center: centerPosition,
@@ -717,16 +671,13 @@ var navigateTo = function (center)
  */
 function showLocation() {
     if (navigator.geolocation) {
-        if (window.location.protocol === "http:")
-        {
+        if (window.location.protocol === "http:") {
             navigator.geolocation.getCurrentPosition(function (geopositionObj) {
                 // TODO: position and display location icon
             }
             );
-        } else
-        {
-            if (confirm("Lokalisering fungerer bare over https (sikker tilkobling mellom nettleser og tjener). Klikk OK for å gå til sikker tilkobling."))
-            {
+        } else {
+            if (confirm("Lokalisering fungerer bare over https (sikker tilkobling mellom nettleser og tjener). Klikk OK for å gå til sikker tilkobling.")) {
                 window.location = "https:" + window.location.href.substring(window.location.protocol.length);
             }
         }
@@ -737,16 +688,13 @@ function showLocation() {
 
 function navToLocation() {
     if (navigator.geolocation) {
-        if (window.location.protocol === "https:")
-        {
+        if (window.location.protocol === "https:") {
             navigator.geolocation.getCurrentPosition(function (geopositionObj) {
                 navigateTo([geopositionObj.coords.longitude, geopositionObj.coords.latitude]);
             }
             );
-        } else
-        {
-            if (confirm("Lokalisering fungerer bare over https (sikker tilkobling mellom nettleser og tjener). Klikk OK for å gå til sikker tilkobling."))
-            {
+        } else {
+            if (confirm("Lokalisering fungerer bare over https (sikker tilkobling mellom nettleser og tjener). Klikk OK for å gå til sikker tilkobling.")) {
                 window.location = "https:" + window.location.href.substring(window.location.protocol.length);
             }
         }
@@ -760,41 +708,36 @@ function navToLocation() {
  * @param {type} selectedSeason
  * @returns {undefined}
  */
-function initSeasonSelectList(selectedSeason)
-{
+function initSeasonSelectList(selectedSeason) {
     // What's the current year?
     var thisYear = new Date().getFullYear();
     // How many years do we go back?
     $.ajax({
         url: "/rest/observation/first/" + phytophthora.organismId
     })
-            .done(function (data) {
-                var time = moment(data);
-                var firstYear = time.toDate().getFullYear();
-                // Loop gjennom år, lag valgliste :-)
-                var startSeasonList = document.getElementById("startSeason");
-                for (var i = firstYear; i <= thisYear; i++)
-                {
-                    var yearOpt = new Option("", i);
-                    yearOpt.innerHTML = i + " &rarr;"
-                    if (i == selectedSeason)
-                    {
-                        yearOpt.selected = true;
-                    }
-                    startSeasonList.options[startSeasonList.options.length] = yearOpt;
-                }
-            })
-            .fail(function (jqXHR, textStatus, errorThrown) {
-                if(jqXHR.status==404)
-                {
-                    alert("Could not find any observations of organism with id=" + phytophthora.organismId);
-                    document.getElementById("startSeason").options[0] = new Option("" + thisYear, thisYear);
-                }
-                else
-                {
-                    alert(textStatus + ": " + errorThrown);
+        .done(function (data) {
+            var time = moment(data);
+            var firstYear = time.toDate().getFullYear();
+            // Loop gjennom år, lag valgliste :-)
+            var startSeasonList = document.getElementById("startSeason");
+            for (var i = firstYear; i <= thisYear; i++) {
+                var yearOpt = new Option("", i);
+                yearOpt.innerHTML = i + " &rarr;"
+                if (i == selectedSeason) {
+                    yearOpt.selected = true;
                 }
-            });
+                startSeasonList.options[startSeasonList.options.length] = yearOpt;
+            }
+        })
+        .fail(function (jqXHR, textStatus, errorThrown) {
+            if (jqXHR.status == 404) {
+                alert("Could not find any observations of organism with id=" + phytophthora.organismId);
+                document.getElementById("startSeason").options[0] = new Option("" + thisYear, thisYear);
+            }
+            else {
+                alert(textStatus + ": " + errorThrown);
+            }
+        });
 
 }
 
diff --git a/src/main/webapp/templates/observationForm.ftl b/src/main/webapp/templates/observationForm.ftl
index 4945cddf3dc3a466fb916e030ac26cb8e97f097a..ed54a05a75721de21b52149fca468f43adb1bba6 100755
--- a/src/main/webapp/templates/observationForm.ftl
+++ b/src/main/webapp/templates/observationForm.ftl
@@ -42,7 +42,7 @@
 	<script type="text/javascript" src="/js/poiFormMap.js"></script>
 	<script type="text/javascript">
 		var organizationId = ${user.organizationId.organizationId};
-        var selectedCropId = <#if observation.cropOrganism?has_content>${observation.cropOrganism.organismId}<#else>null</#if>;
+        var selectedCropId = <#if observation.cropOrganism?has_content>${observation.cropOrganism.organismId?c}<#else>null</#if>;
 
 
 		$(document).ready(function() {