diff --git a/pom.xml b/pom.xml
index a9064c24f5b71487cfc5f3021acf0c859d1b9003..3d51165fd289fc72ca1f0c7f7e924087ceaa1903 100755
--- a/pom.xml
+++ b/pom.xml
@@ -16,10 +16,9 @@
 
 <repositories>
     <repository>
-    <id>jitpack.io</id>
-    <url>https://jitpack.io</url>
-</repository>
-   
+        <id>jitpack.io</id>
+        <url>https://jitpack.io</url>
+    </repository>
 </repositories>
   <dependencies>
       <dependency>
@@ -63,6 +62,16 @@
       <artifactId>VIPSCommon</artifactId>
       <version>1.0-SNAPSHOT</version>
       <type>jar</type>
+      <exclusions>
+     <exclusion>
+       <groupId>org.python</groupId>
+       <artifactId>jython-standalone</artifactId>
+     </exclusion>
+     <exclusion>
+       <groupId>org.renjin</groupId>
+       <artifactId>renjin-script-engine</artifactId>
+     </exclusion>
+   </exclusions>
     </dependency>
     <dependency>
       <groupId>org.reflections</groupId>
@@ -201,6 +210,7 @@
 	<version>9.4-1211</version>
         <scope>provided</scope>
 </dependency-->
+
   </dependencies>
 
   <build>
diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java
index ed20e1362ff55434eb13ba4846bb7834a3c98f8a..15cf47d3d5648b2c3ca00ca96a73324821df07e2 100755
--- a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java
+++ b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
  * 
  * This file is part of VIPSLogic.
  * VIPSLogic is free software: you can redistribute it and/or modify
@@ -36,8 +36,8 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import no.nibio.vips.logic.entity.Observation;
+import no.nibio.vips.logic.entity.ObservationFormShortcut;
 import no.nibio.vips.logic.entity.ObservationMethod;
-import no.nibio.vips.logic.entity.ObservationStatusType;
 import no.nibio.vips.logic.entity.Organism;
 import no.nibio.vips.logic.entity.Organization;
 import no.nibio.vips.logic.entity.VipsLogicRole;
@@ -58,7 +58,7 @@ import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 
 /**
- * @copyright 2014 <a href="http://www.nibio.no/">NIBIO</a>
+ * @copyright 2014-2017 <a href="http://www.nibio.no/">NIBIO</a>
  * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
  */
 public class ObservationController extends HttpServlet {
@@ -127,9 +127,13 @@ public class ObservationController extends HttpServlet {
                             .collect(Collectors.toList());
                 }
                 
+                // Check for form shortcuts
+                List<ObservationFormShortcut> shortcuts = SessionControllerGetter.getObservationBean().getObservationFormShortcuts(user.getOrganizationId());
+                
                 Collections.sort(observations);
                 Collections.reverse(observations);
                 List<Organism> allPests = em.createNamedQuery("Organism.findAllPests").getResultList();
+                request.setAttribute("shortcuts", shortcuts);
                 request.setAttribute("allPests", SessionControllerGetter.getOrganismBean().sortOrganismsByLocalName(allPests, SessionLocaleUtil.getCurrentLocale(request).getLanguage()));
                 request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
                 request.setAttribute("selectedPestOrganismId", pestOrganismId);
@@ -150,15 +154,40 @@ public class ObservationController extends HttpServlet {
                 {
                     try
                     {
+                        
                         Observation observation = new Observation();
+                        // See if there are presets on the URL string
+                        if(request.getParameter("cropOrganismId") != null)
+                        {
+                            observation.setCropOrganism(em.find(Organism.class, Integer.valueOf(request.getParameter("cropOrganismId"))));
+                        }
+                        
+                        List<Organism> allCrops;
+                        if(request.getParameter("organismId") != null)
+                        {
+                            Integer organismId = Integer.valueOf(request.getParameter("organismId"));
+                            observation.setOrganism(em.find(Organism.class, organismId));
+                            // If pest has been selected, include only associated crops
+                            allCrops = SessionControllerGetter.getOrganismBean().getPestCrops(organismId);
+                        }
+                        else
+                        {
+                            allCrops = em.createNamedQuery("Organism.findAllCrops").getResultList();
+                        }
+                        
                         request.setAttribute("observation", observation);
+                        request.setAttribute("shortcut", request.getParameter("observationFormShortcutId") != null ?
+                                    em.find(ObservationFormShortcut.class, Integer.valueOf(request.getParameter("observationFormShortcutId")))
+                                    : null
+                                );
+                        request.setAttribute("hideObservationFormMap", request.getParameter("hideObservationFormMap") != null ? request.getParameter("hideObservationFormMap").equals("true") : false);
+                        request.setAttribute("noBroadcast", request.getParameter("noBroadcast") != null);
                         request.setAttribute("mapLayers", SessionControllerGetter.getUserBean().getMapLayerJSONForUser(user));
                         request.setAttribute("defaultMapCenter",user.getOrganizationId().getDefaultMapCenter());
                         request.setAttribute("defaultMapZoom", user.getOrganizationId().getDefaultMapZoom());
                         request.setAttribute("locationPointOfInterests", SessionControllerGetter.getPointOfInterestBean().getRelevantPointOfInterestsForUser(user));
                         List<Organism> allPests = em.createNamedQuery("Organism.findAllPests").getResultList();
                         request.setAttribute("allPests", SessionControllerGetter.getOrganismBean().sortOrganismsByLocalName(allPests, SessionLocaleUtil.getCurrentLocale(request).getLanguage()));
-                        List<Organism> allCrops = em.createNamedQuery("Organism.findAllCrops").getResultList();
                         request.setAttribute("allCrops", SessionControllerGetter.getOrganismBean().sortOrganismsByLocalName(allCrops, SessionLocaleUtil.getCurrentLocale(request).getLanguage()));
                         // Hierarchy categories
                         request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
@@ -190,6 +219,7 @@ public class ObservationController extends HttpServlet {
                         Integer observationId = Integer.valueOf(request.getParameter("observationId"));
                         Observation observation = SessionControllerGetter.getObservationBean().getObservation(observationId);//em.find(Observation.class, observationId);
                         request.setAttribute("observation", observation);
+                        request.setAttribute("noBroadcast", request.getParameter("noBroadcast") != null);
                         request.setAttribute("mapLayers", SessionControllerGetter.getUserBean().getMapLayerJSONForUser(user));
                         //System.out.println(observation.getGeoinfo());
                         request.setAttribute("defaultMapCenter",user.getOrganizationId().getDefaultMapCenter());
@@ -277,6 +307,7 @@ public class ObservationController extends HttpServlet {
                             observation.setObservationText(formValidation.getFormField("observationText").getWebValue());
                             observation.setObservationData(formValidation.getFormField("observationData").getWebValue());
                             observation.setIsQuantified(formValidation.getFormField("isQuantified").getWebValue() != null);
+                            observation.setLocationIsPrivate(formValidation.getFormField("locationIsPrivate").getWebValue() != null);
                             observation.setBroadcastMessage(formValidation.getFormField("broadcastMessage").getWebValue() != null);
 
                             boolean sendNotification = false;    
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 68311535e771bf22bfa05ee261e40a6a729c8ecd..6ac249a898286a269b87bb31b8795ea93e9ced03 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
@@ -42,6 +42,7 @@ import no.nibio.vips.logic.entity.Message;
 import no.nibio.vips.logic.entity.MessageIllustration;
 import no.nibio.vips.logic.entity.MessageIllustrationPK;
 import no.nibio.vips.logic.entity.Observation;
+import no.nibio.vips.logic.entity.ObservationFormShortcut;
 import no.nibio.vips.logic.entity.ObservationIllustration;
 import no.nibio.vips.logic.entity.ObservationIllustrationPK;
 import no.nibio.vips.logic.entity.ObservationStatusType;
@@ -560,5 +561,11 @@ public class ObservationBean {
                 .getSingleResult();
         this.deleteObservation(observation.getObservationId());
     }
+
+    public List<ObservationFormShortcut> getObservationFormShortcuts(Organization organization) {
+        return em.createNamedQuery("ObservationFormShortcut.findByOrganizationId").
+                setParameter("organizationId", organization.getOrganizationId())
+                .getResultList();
+    }
     
 }
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
index 7728d10d225c986ab3efadf734890c4ad7534785..e1a6a639e2117336403d1f2ce625a91fff241a78 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java
@@ -111,6 +111,15 @@ public class OrganismBean {
         }
         return retVal;
     }
+    
+    public List<Organism> getCropChildren(Organism crop)
+    {
+        List<Organism> children = em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", crop.getOrganismId()).getResultList();
+        List<Organism> grandChildren = new ArrayList();
+        children.stream().forEach(childCrop -> grandChildren.addAll(this.getCropChildren(childCrop)));
+        children.addAll(grandChildren);
+        return children;
+    }
 
     public List<ExternalResource> getUnusedExternalResourcesForOrganism(Organism organism) {
         StringBuilder sql = new StringBuilder()
@@ -264,10 +273,9 @@ public class OrganismBean {
     {
         List<Organism> cropList = this.getAllCrops();
         Map<Integer, Organism> cropMap = new HashMap<>();
-        for(Organism crop:cropList)
-        {
+        cropList.forEach((crop) -> {
             cropMap.put(crop.getOrganismId(), crop);
-        }
+        });
         return cropMap;
     }
 
@@ -284,6 +292,42 @@ public class OrganismBean {
         }
     }
     
+    /**
+     * 
+     * @param pestOrganismId
+     * @return the crops associated with this pest (in the public.crop_pest database
+     */
+    public List<Organism> getPestCrops(Integer pestOrganismId)
+    {
+        /*Integer[] pestOrganismIds = {pestOrganismId};
+        List<CropPest> cropPests = em.createNamedQuery("CropPest.findByPestOrganismId")
+                .setParameter("pestOrganismId", pestOrganismId)
+                .getResultList();
+        */
+        List<CropPest> cropPests = em.createNativeQuery("SELECT * FROM public.crop_pest where :pestOrganismId = ANY(pest_organism_ids)", CropPest.class)
+                .setParameter("pestOrganismId", pestOrganismId)
+                .getResultList();
+        
+        /*System.out.println("PestId=" + pestOrganismId);
+        Syem.out.println("cropPests.size()=" + cropPests.size());*/
+        
+        // Using map to avoid potential duplicates
+        Map<Integer, Organism> pestCrops = new HashMap();
+        if(cropPests != null)
+        {
+            cropPests.stream().forEach(cropPest->{
+                Organism crop = em.find(Organism.class, cropPest.getCropOrganismId());
+                pestCrops.put(crop.getOrganismId(), crop);
+                if(cropPest.getIncludeAllChildCrops())
+                {
+                    this.getCropChildren(crop).stream().forEach(cropChild->pestCrops.put(cropChild.getOrganismId(), cropChild));
+                }
+            });
+        }
+        
+        return new ArrayList<>(pestCrops.values());
+    }
+    
     /**
      * Searching recursively upwards in organism tree to find a cropPest.
      * @param cropOrganismId id of the crop
diff --git a/src/main/java/no/nibio/vips/logic/entity/CropPest.java b/src/main/java/no/nibio/vips/logic/entity/CropPest.java
index 20bf148e582433fc1f7643216b803b6bf10d1a31..c8250cdd1b3b4eec9e248140bd2229209c2b3d92 100755
--- a/src/main/java/no/nibio/vips/logic/entity/CropPest.java
+++ b/src/main/java/no/nibio/vips/logic/entity/CropPest.java
@@ -46,6 +46,7 @@ import org.hibernate.annotations.TypeDefs;
     @NamedQuery(name = "CropPest.findAll", query = "SELECT c FROM CropPest c"),
     @NamedQuery(name = "CropPest.findByCropOrganismId", query = "SELECT c FROM CropPest c WHERE c.cropOrganismId = :cropOrganismId"),
     @NamedQuery(name = "CropPest.findByPestOrganismIds", query = "SELECT c FROM CropPest c WHERE c.pestOrganismIds = :pestOrganismIds"),
+    @NamedQuery(name = "CropPest.findByPestOrganismId", query = "SELECT c FROM CropPest c WHERE :pestOrganismId IN (c.pestOrganismIds)"),
     @NamedQuery(name = "CropPest.findByIncludeAllChildCrops", query = "SELECT c FROM CropPest c WHERE c.includeAllChildCrops = :includeAllChildCrops")})
 public class CropPest implements Serializable {
 
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 85f18cb7cde9a9ed4b801d57d43cea80cc32e1e7..0329a9d5cd116ecd736be349ffe5b9297fafcb0b 100755
--- a/src/main/java/no/nibio/vips/logic/entity/Observation.java
+++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java
@@ -94,6 +94,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
     private String observationData;
     private Boolean isQuantified;
     private Boolean broadcastMessage;
+    private Boolean locationIsPrivate;
     
     private String observationDataSchema;
     
@@ -551,4 +552,19 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         this.location = location;
     }
 
+    /**
+     * @return the locationIsPrivate
+     */
+    @Column(name = "location_is_private")
+    public Boolean getLocationIsPrivate() {
+        return locationIsPrivate;
+    }
+
+    /**
+     * @param locationIsPrivate the locationIsPrivate to set
+     */
+    public void setLocationIsPrivate(Boolean locationIsPrivate) {
+        this.locationIsPrivate = locationIsPrivate;
+    }
+
 }
diff --git a/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcut.java b/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcut.java
new file mode 100644
index 0000000000000000000000000000000000000000..350cb424b77543a840f94c4d312915f775ca1a6e
--- /dev/null
+++ b/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcut.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSLogic.
+ * VIPSLogic is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSLogic 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
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSLogic.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.logic.entity;
+
+import java.io.Serializable;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+@Entity
+@Table(name = "observation_form_shortcut")
+@XmlRootElement
+@NamedQueries({
+    @NamedQuery(name = "ObservationFormShortcut.findAll", query = "SELECT o FROM ObservationFormShortcut o")
+    , @NamedQuery(name = "ObservationFormShortcut.findByObservationFormShortcutId", query = "SELECT o FROM ObservationFormShortcut o WHERE o.observationFormShortcutId = :observationFormShortcutId")
+    , @NamedQuery(name = "ObservationFormShortcut.findByOrganizationId", query = "SELECT o FROM ObservationFormShortcut o WHERE o.organizationId = :organizationId")
+    , @NamedQuery(name = "ObservationFormShortcut.findByDefaultLabel", query = "SELECT o FROM ObservationFormShortcut o WHERE o.defaultLabel = :defaultLabel")
+})
+public class ObservationFormShortcut implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Basic(optional = false)
+    @Column(name = "observation_form_shortcut_id")
+    private Integer observationFormShortcutId;
+    @Column(name = "organization_id")
+    private Integer organizationId;
+    @Size(max = 255)
+    @Column(name = "default_label")
+    private String defaultLabel;
+    @Size(max = 2047)
+    @Column(name = "form_query_param_string")
+    private String formQueryParamString;
+    @Size(max = 2047)
+    @Column(name = "list_query_param_string")
+    private String listQueryParamString;
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "observationFormShortcutId", fetch = FetchType.EAGER)
+    private Set<ObservationFormShortcutLocale> shortcutLocaleSet;
+
+    public ObservationFormShortcut() {
+    }
+
+    public ObservationFormShortcut(Integer observationFormShortcutId) {
+        this.observationFormShortcutId = observationFormShortcutId;
+    }
+
+    public Integer getObservationFormShortcutId() {
+        return observationFormShortcutId;
+    }
+
+    public void setObservationFormShortcutId(Integer observationFormShortcutId) {
+        this.observationFormShortcutId = observationFormShortcutId;
+    }
+
+    public String getDefaultLabel() {
+        return defaultLabel;
+    }
+
+    public void setDefaultLabel(String defaultLabel) {
+        this.defaultLabel = defaultLabel;
+    }
+
+    public String getFormQueryParamString() {
+        return formQueryParamString;
+    }
+
+    public void setFormQueryParamString(String formQueryParamString) {
+        this.formQueryParamString = formQueryParamString;
+    }
+
+    public String getLocalLabel(String language)
+    {
+        if(this.shortcutLocaleSet == null || this.shortcutLocaleSet.isEmpty())
+        {
+            return this.getDefaultLabel();
+        }
+        ObservationFormShortcutLocale l = this.shortcutLocaleSet.stream()
+                .filter(localS -> localS.getLocale().equals(language))
+                .findAny()
+                .orElse(
+                    this.shortcutLocaleSet.stream()
+                    .filter(localS -> localS.getLocale().equals("en"))
+                    .findAny()
+                    .orElse(null)
+                );
+        return l != null ? l.getLabel() : this.getDefaultLabel();
+    }
+    
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        hash += (observationFormShortcutId != null ? observationFormShortcutId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        // TODO: Warning - this method won't work in the case the id fields are not set
+        if (!(object instanceof ObservationFormShortcut)) {
+            return false;
+        }
+        ObservationFormShortcut other = (ObservationFormShortcut) object;
+        if ((this.observationFormShortcutId == null && other.observationFormShortcutId != null) || (this.observationFormShortcutId != null && !this.observationFormShortcutId.equals(other.observationFormShortcutId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "no.nibio.vips.logic.entity.ObservationFormShortcut[ observationFormShortcutId=" + observationFormShortcutId + " ]";
+    }
+
+    /**
+     * @return the organizationId
+     */
+    public Integer getOrganizationId() {
+        return organizationId;
+    }
+
+    /**
+     * @param organizationId the organizationId to set
+     */
+    public void setOrganizationId(Integer organizationId) {
+        this.organizationId = organizationId;
+    }
+
+    /**
+     * @return the listQueryParamString
+     */
+    public String getListQueryParamString() {
+        return listQueryParamString;
+    }
+
+    /**
+     * @param listQueryParamString the listQueryParamString to set
+     */
+    public void setListQueryParamString(String listQueryParamString) {
+        this.listQueryParamString = listQueryParamString;
+    }
+
+}
diff --git a/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcutLocale.java b/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcutLocale.java
new file mode 100644
index 0000000000000000000000000000000000000000..470eaeba5314c93180343c6989b977b37e67fb7e
--- /dev/null
+++ b/src/main/java/no/nibio/vips/logic/entity/ObservationFormShortcutLocale.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSLogic.
+ * VIPSLogic is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSLogic 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
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSLogic.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.logic.entity;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+@Entity
+@Table(name = "observation_form_shortcut_locale")
+@XmlRootElement
+@NamedQueries({
+    @NamedQuery(name = "ObservationFormShortcutLocale.findAll", query = "SELECT o FROM ObservationFormShortcutLocale o")
+    , @NamedQuery(name = "ObservationFormShortcutLocale.findByObservationFormShortcutId", query = "SELECT o FROM ObservationFormShortcutLocale o WHERE o.observationFormShortcutId = :observationFormShortcutId")
+    , @NamedQuery(name = "ObservationFormShortcutLocale.findByLocale", query = "SELECT o FROM ObservationFormShortcutLocale o WHERE o.locale = :locale")
+    , @NamedQuery(name = "ObservationFormShortcutLocale.findByLabel", query = "SELECT o FROM ObservationFormShortcutLocale o WHERE o.label = :label")})
+public class ObservationFormShortcutLocale implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Basic(optional = false)
+    @Column(name = "observation_form_shortcut_id")
+    private Integer observationFormShortcutId;
+    @Size(max = 10)
+    @Column(name = "locale")
+    private String locale;
+    @Size(max = 255)
+    @Column(name = "label")
+    private String label;
+
+    public ObservationFormShortcutLocale() {
+    }
+
+    public ObservationFormShortcutLocale(Integer observationFormShortcutId) {
+        this.observationFormShortcutId = observationFormShortcutId;
+    }
+
+    public Integer getObservationFormShortcutId() {
+        return observationFormShortcutId;
+    }
+
+    public void setObservationFormShortcutId(Integer observationFormShortcutId) {
+        this.observationFormShortcutId = observationFormShortcutId;
+    }
+
+    public String getLocale() {
+        return locale;
+    }
+
+    public void setLocale(String locale) {
+        this.locale = locale;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        hash += (observationFormShortcutId != null ? observationFormShortcutId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        // TODO: Warning - this method won't work in the case the id fields are not set
+        if (!(object instanceof ObservationFormShortcutLocale)) {
+            return false;
+        }
+        ObservationFormShortcutLocale other = (ObservationFormShortcutLocale) object;
+        if ((this.observationFormShortcutId == null && other.observationFormShortcutId != null) || (this.observationFormShortcutId != null && !this.observationFormShortcutId.equals(other.observationFormShortcutId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "no.nibio.vips.logic.entity.ObservationFormShortcutLocale[ observationFormShortcutId=" + observationFormShortcutId + " ]";
+    }
+
+}
diff --git a/src/main/java/no/nibio/vips/logic/service/VIPSMobileService.java b/src/main/java/no/nibio/vips/logic/service/VIPSMobileService.java
index afa72b28851ab91762e304a5dd7810be88e8b50d..2d4e345413349b9af188dcc39e737c1aa11099ad 100755
--- a/src/main/java/no/nibio/vips/logic/service/VIPSMobileService.java
+++ b/src/main/java/no/nibio/vips/logic/service/VIPSMobileService.java
@@ -152,7 +152,9 @@ public class VIPSMobileService {
             List<Observation> broadcastObservations = SessionControllerGetter.getObservationBean().getBroadcastObservations(organizationId);
             // Making an observation message valid for 3 months by default
             Calendar cal = Calendar.getInstance();
-            broadcastObservations.stream().forEach(
+            broadcastObservations.stream().filter(
+                    obs -> obs.getBroadcastMessage() && !obs.getObservationHeading().trim().isEmpty()
+            ).forEach(
                     obs -> {
                         cal.setTime(obs.getTimeOfObservation());
                         cal.add(Calendar.MONTH, 3);
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
index afa6c26a52ae9302567ae176ed9132adb3ed7961..50323a83993dd49c1c2c95778c58182c0a0a25be 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
@@ -431,3 +431,8 @@ cropCategoryUpdated=Crop category was updated
 observationMap=Observation map
 isForecastLocation=Is forecast location
 viewOthersObservations=View observations made by others
+registrationOf=Registration of
+observationData=Observation data
+registrationShortcuts=Registration shortcuts
+filterList=Filter list
+locationIsPrivate=Location is private
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
index a3c5a0a21603a813b0215fb9cac442396116459e..57fa0806320d7ef13fa8dbdcb6342b61411f04f5 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
@@ -431,3 +431,8 @@ cropCategoryUpdated=Crop category was updated
 observationMap=Observation map
 isForecastLocation=Is forecast location
 viewOthersObservations=View observations made by others
+registrationOf=Registration of
+observationData=Observation data
+registrationShortcuts=Registration shortcuts
+filterList=Filter list
+locationIsPrivate=Location is private
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
index 6bd7d249b02831c4fbe158037b4246ea26e42ddc..81cabccbbbf7edd8f6b4eafa4308ac0c6d0e4f83 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
@@ -430,3 +430,8 @@ cropCategoryUpdated=Crop category was updated
 observationMap=Observation map
 isForecastLocation=Is forecast location
 viewOthersObservations=View observations made by others
+registrationOf=Registration of
+observationData=Observation data
+registrationShortcuts=Registration shortcuts
+filterList=Filter list
+locationIsPrivate=Location is private
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 39eae359965c11e7fed980743f8a26d3998e8054..5347c0f24ae7b6e16b5c482ad37aa02bea3db3a2 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
@@ -431,3 +431,8 @@ cropCategoryUpdated=Kulturkategorien ble oppdatert
 observationMap=Observasjonskart
 isForecastLocation=Er en varselslokalitet
 viewOthersObservations=Se observasjoner gjort av andre
+registrationOf=Registrering av
+observationData=Observasjonsdata
+registrationShortcuts=Snarveier for registrering
+filterList=Filtr\u00e9r lista
+locationIsPrivate=Lokalitet skal ikke offentliggj\u00f8res
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
index 885269aef2422c6b6c15d714bf679029c30211cd..6e581f4039c1f13b11b0ea36b5d485fc6e402623 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
@@ -431,3 +431,8 @@ cropCategoryUpdated=Crop category was updated
 observationMap=Observation map
 isForecastLocation=Is forecast location
 viewOthersObservations=View observations made by others
+registrationOf=Registration of
+observationData=Observation data
+registrationShortcuts=Registration shortcuts
+filterList=Filter list
+locationIsPrivate=Location is private
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
index 01a2f36473fa9030a5b64d602528f514da2d654e..bc2ded2de102323d4085cf0aaccb67a94cce3a61 100755
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
@@ -428,3 +428,8 @@ uppercase=\u5927\u5199
 allSystems=\u6240\u6709\u7cfb\u7edf
 cropCategoriesFor=\u4f5c\u7269\u7c7b\u522b\u4e3a
 viewOthersObservations=View observations made by others
+registrationOf=Registration of
+observationData=Observation data
+registrationShortcuts=Registration shortcuts
+filterList=Filter list
+locationIsPrivate=Location is private
diff --git a/src/main/webapp/formdefinitions/observationForm.json b/src/main/webapp/formdefinitions/observationForm.json
index 03d1f0ea878e2d8ca31a9b0d5b09b3e1a899836b..df120cc8aea4cdb79524dd796d245faaa91e170a 100755
--- a/src/main/webapp/formdefinitions/observationForm.json
+++ b/src/main/webapp/formdefinitions/observationForm.json
@@ -57,6 +57,11 @@
             "fieldType" : "SELECT_SINGLE",
             "required" : false
         },
+        {
+            "name" : "locationIsPrivate",
+            "dataType" : "STRING",
+            "required" : false
+        },
         {
             "name" : "isQuantified",
             "dataType" : "STRING",
diff --git a/src/main/webapp/templates/observationForm.ftl b/src/main/webapp/templates/observationForm.ftl
index 0527d29a5e7a9ca21a7f97a710439e9eee372beb..f3618a3237beec21e32ed735982ad5ccb80c7e47 100755
--- a/src/main/webapp/templates/observationForm.ftl
+++ b/src/main/webapp/templates/observationForm.ftl
@@ -1,5 +1,5 @@
 <#-- 
-    Copyright (c) 2014 NIBIO <http://www.nibio.no/>. 
+    Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
   
   This file is part of VIPSLogic.
   VIPSLogic is free software: you can redistribute it and/or modify
@@ -69,9 +69,9 @@
 			<#if observation.observationData?has_content>
 				observationData = ${observation.observationData};
 				getDataSchema(${observation.organism.organismId}, organizationId);
-			<#else>
+			<#elseif observation.organism?has_content>
 			// Setting 
-				
+				initObservationData(${observation.organism.organismId},organizationId);
 			</#if>
 			
 			// Activating file selection
@@ -245,11 +245,19 @@
 		}
 		
 		
-		// If locationPointOfInterestId is selected, show map for locations
+		// If locationPointOfInterestId is selected OR observation drawing map is deliberately disabled, 
+                // show map for locations
 		// If not, show the observation drawing map
+                var hideObservationFormMap = ${hideObservationFormMap?c!"false"};
 		function showCorrectMap(){
 			var locationList = document.getElementById("locationPointOfInterestId");
-			if(locationList.options[locationList.options.selectedIndex].value != "-1")
+                        if(hideObservationFormMap && locationList.options[locationList.options.selectedIndex].value == "-1")
+                        {
+                            document.getElementById("observationFormMap").style.display="none";
+                            document.getElementById("poiFormMap").style.display="block";
+                            initLocationMap(null);
+                        }
+			else if(locationList.options[locationList.options.selectedIndex].value != "-1")
 			{
 				document.getElementById("observationFormMap").style.display="none";
 				document.getElementById("poiFormMap").style.display="block";
@@ -374,12 +382,24 @@
                         cropOrganismIdList.options[cropOrganismIdList.options.length] = theRest[i];
                     }
                 }
+                <#if noBroadcast>
+                /**
+                 * In the unlikely event that the user in a pre-filled form decides to
+                 * change the organism, we'll update the observationText and heading   
+                 */
+                function updateHeadingAndText(organismName)
+                {
+                    var registrationOfText = "${i18nBundle.registrationOf} " + organismName;
+                    document.getElementById("observationHeading").value = registrationOfText;
+                    document.getElementById("observationText").value = registrationOfText;
+                }
+                </#if>
 	</script>
 </#macro>
 <#macro page_contents>
 <div class="singleBlockContainer">
 	<p><a href="/observation" class="btn btn-default back" role="button">${i18nBundle.back}</a><#if observation.observationId?has_content><a href="/observation?action=newObservationForm" class="btn btn-default" role="button">${i18nBundle.addNew}</a></#if></p>
-        <h1><#if observation.observationId?has_content>${i18nBundle.editObservation}<#else>${i18nBundle.newObservation}</#if></h1>
+        <h1><#if observation.observationId?has_content>${i18nBundle.editObservation}<#else>${i18nBundle.newObservation}</#if><#if shortcut?has_content> - ${shortcut.getLocalLabel(currentLocale.language)?lower_case}</#if></h1>
         <div id="errorMsgEl" class="alert alert-danger" <#if !formValidation?has_content> style="display:none;"</#if>>
 		<#if formValidation?has_content>${formValidation.validationMessages?replace("\n", "<br>")}</#if>
 	</div>
@@ -389,7 +409,7 @@
 	<div class="row">
 		<div class="col-md-6">
 			<#assign formId = "observationForm">
-			<form id="${formId}" role="form" action="/observation?action=observationFormSubmit" enctype="multipart/form-data" method="POST" onsubmit="this['geoInfo'].value=getFeatures();try{mw.save();this['observationData'].value=JSON.stringify(mw.toInspect);return validateForm(this) && validateGIS(this);}catch(e){console.log(e.message);console.log(e);return false;}">
+			<form id="${formId}" role="form" action="/observation?action=observationFormSubmit" enctype="multipart/form-data" method="POST" onsubmit="this['geoInfo'].value=getFeatures();try{mw.save();this['observationData'].value=JSON.stringify(mw.toInspect);console.info('validateGIS = ' + (validateGIS(this)));return validateForm(this) && validateGIS(this);}catch(e){console.log(e.message);console.log(e);return false;}">
 			<!--form id="${formId}" role="form" action="/observation?action=observationFormSubmit" method="POST" onsubmit="this['geoInfo'].value=getFeatures();mw.save();console.log(this['observationData']);this['observationData'].value=JSON.stringify(mw.toInspect);return validateForm(this);"-->
 			<!--form id="${formId}" role="form" action="/observation?action=observationFormSubmit" method="POST" onsubmit="this['geoInfo'].value=getFeatures();mw.save();console.log(this['observationData']);this['observationData'].value=JSON.stringify(mw.toInspect);validateForm(this);return false;"-->
 			  <input type="hidden" name="geoInfo" value=""/>
@@ -407,17 +427,17 @@
                           </#if>
 			   <div class="form-group">
 			    <label for="cropOrganismId">${i18nBundle.cropOrganismId}</label>
-			    <select class="form-control" id="cropOrganismIdList" name="cropOrganismId" <#if observation.organism?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly" <#else> onblur="validateField(this);" onchange="updateCropPests();"</#if>>
-				<#if ! observation.organism?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
+			    <select class="form-control" id="cropOrganismIdList" name="cropOrganismId" <#if observation.observationId?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly" <#else> onblur="validateField(this);" onchange="updateCropPests();"</#if>>
+				<#if ! observation.observationId?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
 					<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropOrganismId?lower_case}</option>
 					<option value="-10"<#if (observation.cropOrganism?has_content && observation.cropOrganism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option>
-					<#list allCrops as cropOrganism>
+                                        <#list allCrops as cropOrganism>
                                                 <#if cropOrganism.hierarchyCategoryId <= 121>
 						<option value="${cropOrganism.organismId}"
 							<#if (observation.cropOrganism?has_content && observation.cropOrganism.organismId == cropOrganism.organismId)>selected="selected"</#if>
 						>${cropOrganism.getLocalName(currentLocale.language)!""} (${cropOrganism.latinName!""}) ${hierarchyCategories.getName(cropOrganism.hierarchyCategoryId)?upper_case}</option>
                                                 </#if>
-					</#list>
+					</#list>                                        
 				<#else>
 					<#list allCrops as cropOrganism>
 						<#if (observation.cropOrganism?has_content && observation.cropOrganism.organismId == cropOrganism.organismId)>
@@ -430,7 +450,7 @@
 			  </div>
 			  <div class="form-group">
 			    <label for="organismId">${i18nBundle.organism}</label>
-			    <select class="form-control" name="organismId" <#if observation.organism?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly"<#else>onchange="initObservationData(this.options[this.options.selectedIndex].value,organizationId);" onblur="validateField(this);"</#if>>
+			    <select class="form-control" name="organismId" <#if observation.organism?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly"<#else>onchange="<#if noBroadcast>updateHeadingAndText(this.options[this.options.selectedIndex].text);</#if>initObservationData(this.options[this.options.selectedIndex].value,organizationId);" onblur="validateField(this);"</#if>>
 			    	<#if ! observation.organism?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
 				<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.organism?lower_case}</option>
 				<option value="-10"<#if (observation.organism?has_content && observation.organism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option>
@@ -451,12 +471,20 @@
 			    
 			  </div>
 			   <div class="form-group">
-			    <label for="locationPointOfInterestId">${i18nBundle.location}&nbsp;&nbsp;<i class="fa fa-plus-square" aria-hidden="true" style="cursor:pointer;" title="${i18nBundle.addNew}" onclick="addNewLocationPopup();"></i></label>
+                               <label for="locationPointOfInterestId">${i18nBundle.location}&nbsp;&nbsp;<button role="button" type="button" onclick="addNewLocationPopup();">${i18nBundle.addNew}</button></label>
 			    <select class="form-control" name="locationPointOfInterestId" id="locationPointOfInterestId" onchange="showCorrectMap();">
 				<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.location?lower_case}</option>
 			     </select>
 			     <span class="help-block" id="${formId}_locationPointOfInterestId_validation"></span>
 			  </div>
+                          <div class="form-group">
+			  	<div class="checkbox">
+					<label>
+						<input type="checkbox" name="locationIsPrivate"<#if !observation.locationIsPrivate?has_content || observation.locationIsPrivate == false><#else>checked="checked"</#if>/>
+					</label>
+					${i18nBundle.locationIsPrivate}
+			  	</div>
+			  </div>
                           <#setting time_zone=user.organizationId.defaultTimeZone!"UTC">
 			  <div class="form-group">
 			    <label for="timeOfObservation">${i18nBundle.timeOfObservation}</label>
@@ -474,67 +502,52 @@
 			  </div>
 			  <div class="form-group">
 			  <fieldset>
-			  	<legend>Observation data</legend>
+			  	<legend>${i18nBundle.observationData}</legend>
 			  	<div id="metawidget"></div>
 			  </fieldset>
 			  </div>
-			  <!--div class="form-group">
-			    <label for="observedValue">${i18nBundle.observedValue}</label>
-			    <input type="number" class="form-control" name="observedValue" placeholder="${i18nBundle.observedValue}" value="${(observation.observedValue?c)!""}" onblur="validateField(this);"/>
-			    <span class="help-block" id="${formId}_observedValue_validation"></span>
-			  </div>
-			  <div class="form-group">
-			    <label for="denominator">${i18nBundle.denominator}</label>
-			    <input type="number" class="form-control" name="denominator" placeholder="${i18nBundle.denominator}" value="${(observation.denominator?c)!"1"}" onblur="validateField(this);"/>
-			    <span class="help-block" id="${formId}_denominator_validation"></span>
-			  </div-->
-			  <!--div class="form-group">
-			    <label for="observationMethodId">${i18nBundle.observationMethodId}</label>
-			    <select class="form-control" name="observationMethodId" onblur="validateField(this);">
-				<#list observationMethods as observationMethod>
-					<option value="${observationMethod.observationMethodId}"
-						<#if observation.observationMethodId?has_content && observation.observationMethodId.observationMethodId == observationMethod.observationMethodId>selected="selected"</#if>
-					>${i18nBundle("observationMethodTitle_" + observationMethod.observationMethodId)}</option>
-				</#list>
-			     </select>
-			     <span class="help-block" id="${formId}_observationMethodId_validation"></span>
-			  </div-->
+			  <#if !noBroadcast>
 			  <div class="form-group">
 			  	<div class="checkbox">
 					<label>
-						<input type="checkbox" name="broadcastMessage"<#if observation.broadcastMessage?has_content && observation.broadcastMessage == false><#else>checked="checked"</#if>/>
+						<input type="checkbox" name="broadcastMessage"<#if (observation.broadcastMessage?has_content && observation.broadcastMessage == false) || noBroadcast><#else>checked="checked"</#if>/>
 					</label>
 					${i18nBundle.broadcastMessage}
 			  	</div>
 			  </div>
-			  <div class="form-group">
-			    <label for="observationHeading">${i18nBundle.observationHeading}</label>
-			    <input type="text" class="form-control" name="observationHeading" placeholder="" value="${observation.observationHeading!""}" onblur="validateField(this);"/>
-			    <span class="help-block" id="${formId}_observationHeading_validation"></span>
-			  </div>
-			  <div class="form-group">
-			    <label for="observationText">${i18nBundle.observationText}</label>
-			    <textarea class="form-control" name="observationText" placeholder="" >${observation.observationText!""}</textarea>
-			    <span class="help-block" id="${formId}_observationText_validation"></span>
-			  </div>
-			  <#if observation.observationIllustrationSet?has_content && observation.observationIllustrationSet?size == 1>
-				<#assign illustration = observation.observationIllustrationSet?first>
-				<img src="/static/images/observations/${observation.organismId}/${illustration.observationIllustrationPK.fileName}" alt="TODO: Add describing text" class="img-responsive"/>
-				<div class="checkbox">
-				  <label>
-				    <input type="checkbox" name="deleteIllustration" value="true">
-				    ${i18nBundle.deleteIllustration}
-				  </label>
-				</div>
-			</#if>
-			  <div class="form-group">
-				<div class="input-group">
-					<label for="illustration"><#if observation.observationIllustrationSet?has_content && observation.observationIllustrationSet?size == 1>${i18nBundle.replaceIllustration}<#else>${i18nBundle.newIllustration}</#if></label><br/>
-					<span class="btn btn-default btn-file">${i18nBundle.browse}<input type="file" name="illustration"></span>
-					<input type="text" class="form-control" readonly>
-				</div>
-			</div>
-	
+                          
+                            <div class="form-group">
+                              <label for="observationHeading">${i18nBundle.observationHeading}</label>
+                              <input type="text" class="form-control" name="observationHeading" placeholder="" value="${observation.observationHeading!""}" onblur="validateField(this);"/>
+                              <span class="help-block" id="${formId}_observationHeading_validation"></span>
+                            </div>
+                            <div class="form-group">
+                              <label for="observationText">${i18nBundle.observationText}</label>
+                              <textarea class="form-control" name="observationText" placeholder="" >${observation.observationText!""}</textarea>
+                              <span class="help-block" id="${formId}_observationText_validation"></span>
+                            </div>
+                            <#if observation.observationIllustrationSet?has_content && observation.observationIllustrationSet?size == 1>
+                                  <#assign illustration = observation.observationIllustrationSet?first>
+                                  <img src="/static/images/observations/${observation.organismId}/${illustration.observationIllustrationPK.fileName}" alt="TODO: Add describing text" class="img-responsive"/>
+                                  <div class="checkbox">
+                                    <label>
+                                      <input type="checkbox" name="deleteIllustration" value="true">
+                                      ${i18nBundle.deleteIllustration}
+                                    </label>
+                                  </div>
+                          </#if>
+                            <div class="form-group">
+                                  <div class="input-group">
+                                          <label for="illustration"><#if observation.observationIllustrationSet?has_content && observation.observationIllustrationSet?size == 1>${i18nBundle.replaceIllustration}<#else>${i18nBundle.newIllustration}</#if></label><br/>
+                                          <span class="btn btn-default btn-file">${i18nBundle.browse}<input type="file" name="illustration"></span>
+                                          <input type="text" class="form-control" readonly>
+                                  </div>
+                          </div>
+                        <#else>
+                            <!-- broadcastMessage is checkbox, omitting it sets it default to false -->
+                            <input type="hidden" id="observationHeading" name="observationHeading" value="<#if observation.organism?has_content>${i18nBundle.registrationOf} ${observation.organism.getLocalName(currentLocale.language)!""} (${observation.organism.latinName!""})</#if>"/> 
+                            <input type="hidden" id="observationText" name="observationText" value="<#if observation.organism?has_content>${i18nBundle.registrationOf} ${observation.organism.getLocalName(currentLocale.language)!""} (${observation.organism.latinName!""})</#if>"/>
+                        </#if> <!-- visibility -->
 			  <#if user.isObservationAuthority() || user.isOrganizationAdmin() || user.isSuperUser()>
 				  <div class="form-group">
 				    <label for="statusTypeId">${i18nBundle.statusTypeId}</label>
diff --git a/src/main/webapp/templates/observationList.ftl b/src/main/webapp/templates/observationList.ftl
index ff23a9ed42562c9f88d3eef541956e47c779a452..28ef1097f1a8ca1fe73ee9a013da4926609bacbb 100755
--- a/src/main/webapp/templates/observationList.ftl
+++ b/src/main/webapp/templates/observationList.ftl
@@ -27,6 +27,14 @@
 		<div class="alert alert-success">${i18nBundle(messageKey)}</div>
 	</#if>
 	<a href="/observation?action=newObservationForm" class="btn btn-default" role="button">${i18nBundle.addNew}</a>
+        <#if shortcuts?has_content>
+            <h4>${i18nBundle.registrationShortcuts}</h4>
+            <#list shortcuts as shortcut>
+            <a href="/observation?action=newObservationForm${shortcut.formQueryParamString}&observationFormShortcutId=${shortcut.observationFormShortcutId}" class="btn btn-default" role="button">${shortcut.getLocalLabel(currentLocale.language)}</a>
+            </#list>
+            <h4>${i18nBundle.filterList}</h4>
+        </#if>
+        
         <form action="/observation" method="post">
             <select class="form-control" name="statusTypeId" onchange="this.form.submit();">
                     <#list [-1,1,2,3] as statusTypeId>
@@ -55,6 +63,11 @@
             </div>
             </#if>
         </form>
+        <#if shortcuts?has_content>
+            <#list shortcuts as shortcut>
+                <a href="/observation?${shortcut.listQueryParamString}" class="btn btn-default" role="button">${shortcut.getLocalLabel(currentLocale.language)}</a>
+            </#list>
+        </#if>
         <#if observations?size == 0>
         <div class="alert alert-warning">${i18nBundle.noResultsFoundForCriteria}</div>
         </#if>