diff --git a/src/main/java/it/inaf/oats/vospace/SetNodeController.java b/src/main/java/it/inaf/oats/vospace/SetNodeController.java
index d5c62267ba2cc670d0b9f10fca59651990fe40ee..c9b4c7d5f4b11d0c086d949e9a56894082a48734 100644
--- a/src/main/java/it/inaf/oats/vospace/SetNodeController.java
+++ b/src/main/java/it/inaf/oats/vospace/SetNodeController.java
@@ -10,15 +10,20 @@ import it.inaf.oats.vospace.persistence.NodeDAO;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import net.ivoa.xml.vospace.v2.Node;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
 public class SetNodeController extends BaseNodeController {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(SetNodeController.class);
 
     @Autowired
     private NodeDAO nodeDao;
@@ -29,9 +34,10 @@ public class SetNodeController extends BaseNodeController {
     @PostMapping(value = {"/nodes", "/nodes/**"},
             consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
             produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
-    public Node setNode(@RequestBody Node node, User principal, HttpServletRequest request) {
+    public ResponseEntity<Node> setNode(@RequestBody Node node, User principal, HttpServletRequest request) {
 
         String path = getPath();
+        LOG.debug("setNode called for path {}", path);
         
         //The service SHALL throw a HTTP 404 status code including a NodeNotFound 
         //fault in the entity-body if the target Node does not exist
@@ -48,10 +54,15 @@ public class SetNodeController extends BaseNodeController {
         // The service SHALL throw a HTTP 403 status code including a PermissionDenied fault 
         // in the entity-body if the request attempts to modify a read-only Property.
         // This method cannot be used to modify the Node type.
+        String storedNodeType = toBeModifiedNode.getType();
+        String newNodeType = node.getType();
+        if(!storedNodeType.equals(newNodeType)) {
+            LOG.debug("setNode trying to modify type. Stored ", storedNodeType + ", requested " + newNodeType);
+           throw new PermissionDeniedException(path); 
+        }
         // This method cannot be used to modify the accepts or provides list of Views for the Node.
-        // This method cannot be used to create children of a container Node.
-        
-        
+        // For this case, throws exception in NodeDAO
+        // This method cannot be used to create children of a container Node. (Non capisco, Sara)        
         
         // If a parent node in the URI path does not exist then the service SHALL throw a 
         // HTTP 404 status code including a ContainerNotFound fault in the entity-body
@@ -76,19 +87,18 @@ public class SetNodeController extends BaseNodeController {
                             
             }
                     
-        }
-        
-        
+        }        
         
         
         //The service SHOULD throw a HTTP 500 status code including an InternalFault fault 
         // in the entity-body if the operation fails
+        // Done in NodeDAO
        
         // to be fixed
         // A HTTP 200 status code and a Node representation in the entity-body The full 
         // expanded record for the node SHALL be returned, including any xsi:type 
         // specific extensions.
-        return node;
+        return ResponseEntity.ok(nodeDao.setNode(node));
         
     }    
     
diff --git a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
index 5ab50a8927b4d554444a013f210de69826170d74..d8d05985732b2b2ed86997c19bee597280ff1b82 100644
--- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
+++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
@@ -1,9 +1,12 @@
 package it.inaf.oats.vospace.persistence;
 
+import it.inaf.oats.vospace.DeleteNodeController;
 import it.inaf.oats.vospace.datamodel.NodeProperties;
 import it.inaf.oats.vospace.datamodel.NodeUtils;
 import it.inaf.oats.vospace.datamodel.NodeUtils;
 import it.inaf.oats.vospace.exception.InternalFaultException;
+import it.inaf.oats.vospace.exception.NodeNotFoundException;
+import it.inaf.oats.vospace.exception.PermissionDeniedException;
 import java.sql.Array;
 import net.ivoa.xml.vospace.v2.Node;
 import java.sql.PreparedStatement;
@@ -22,6 +25,8 @@ import net.ivoa.xml.vospace.v2.DataNode;
 import net.ivoa.xml.vospace.v2.Property;
 import net.ivoa.xml.vospace.v2.StructuredDataNode;
 import net.ivoa.xml.vospace.v2.View;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -30,6 +35,8 @@ import org.springframework.stereotype.Repository;
 @Repository
 public class NodeDAO {
 
+    private static final Logger LOG = LoggerFactory.getLogger(DeleteNodeController.class);
+    
     @Value("${vospace-authority}")
     private String authority;
 
@@ -46,17 +53,7 @@ public class NodeDAO {
         String path = nodeURI.replaceAll("vos://[^/]+", "");
         String parentPath = NodeUtils.getParentPath(path);
 
-        String sql = "SELECT path, relative_path from "
-                + "node n join node_vos_path p on n.node_id = p.node_id "
-                + "where p.vos_path = ?";
-
-        List<NodePaths> paths = jdbcTemplate.query(conn -> {
-            PreparedStatement ps = conn.prepareStatement(sql);
-            ps.setString(1, parentPath);
-            return ps;
-        }, (row, index) -> {
-            return getPathsFromResultSet(row);
-        });
+        List<NodePaths> paths = getNodePathsFromDB(nodeURI);
 
         if (paths.isEmpty()) {
             throw new IllegalStateException("Unable to find parent node during node creation");
@@ -126,6 +123,101 @@ public class NodeDAO {
         return Optional.of(node);
     }
 
+    
+    public Node setNode(Node newNode) {       
+        
+        // Verify that the node is in the database
+        String nodeURI = newNode.getUri();
+        List<NodePaths> paths = getNodePathsFromDB(nodeURI);
+
+        if (paths.isEmpty()) {
+            throw new IllegalStateException("Unable to find node during node update");
+        }
+        if (paths.size() > 1) {
+            throw new IllegalStateException("Multiple ltree parent paths  during node update");
+        }      
+            
+        // This method cannot be used to modify the accepts or provides list of Views for the Node.
+        // Only DataNodes has Views (see VOSpace Data Model
+        // Check if trying to change views getting Views (if present) of the modified node 
+        if (newNode instanceof DataNode) {
+            DataNode dataNode = (DataNode)newNode;
+            List<View> requestedAcceptedViews = dataNode.getAccepts();           
+            List<View> savedAcceptedViews = getAcceptedViewsFromDB(paths.get(0).getPath());
+            // Get the Views of the saved node
+            List<View> requestedProvidedViews = dataNode.getProvides();
+            List<View> savedProvidedViews = getProvidedViewsFromDB(paths.get(0).getPath());
+            
+            if (!requestedAcceptedViews.isEmpty()) {
+                //se sono non nulle, devo fare i controlli, altrimenti di sicuro l'utente non sta chiedendo di cambiarle
+                // Check if requestedAcceptedViews are different from the already stored
+                if (!checkIfViewsAreEquals(requestedAcceptedViews,savedAcceptedViews)) {
+                    LOG.debug("setNode trying to modify accepted Views.");
+                    throw new PermissionDeniedException("Trying to modify accepted views");
+                }
+            }
+            
+            if (!requestedProvidedViews.isEmpty()) {
+                //se sono non nulle, devo fare i controlli, altrimenti di sicuro l'utente non sta chiedendo di cambiarle
+                // Check if requestedAcceptedViews are different from the already stored
+                if (!checkIfViewsAreEquals(requestedProvidedViews,savedProvidedViews)) {
+                    LOG.debug("setNode trying to modify provided Views.");
+                    throw new PermissionDeniedException("Trying to modify provided views");
+                }     
+            }
+        }
+        
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append("UPDATE node");
+        sb.append(" SET owner_id = ?, group_read = ?, group_write = ?, is_public = ? " );
+        sb.append(" FROM node_vos_path p WHERE p.vos_path = ? AND p.node_id = node.node_id ");
+
+        jdbcTemplate.update(conn -> {
+            PreparedStatement ps = conn.prepareStatement(sb.toString());
+            int i = 0;
+            ps.setString(++i, NodeProperties.getPropertiesStringByURI(newNode, NodeProperties.getPropertyURI("creator")));
+            ps.setArray(++i, fromPropertyToArray(ps, NodeProperties.getPropertiesStringByURI(newNode, NodeProperties.getPropertyURI("groupread"))));
+            ps.setArray(++i, fromPropertyToArray(ps, NodeProperties.getPropertiesStringByURI(newNode, NodeProperties.getPropertyURI("groupwrite"))));
+            ps.setBoolean(++i, Boolean.valueOf(NodeProperties.getPropertiesStringByURI(newNode, NodeProperties.getPropertyURI("publicread"))));
+            ps.setString(++i, paths.get(0).getPath());
+            return ps;
+        });
+        
+        return newNode;
+        
+        
+    }
+    
+    
+    private Optional<Node> getNode(String path) {
+        
+        String sql = "SELECT node_id, type, async_trans, sticky, busy_state, creator_id, group_read, group_write,\n"
+                + "is_public, content_length, created_on, last_modified, accept_views, provide_views \n"
+                + "FROM node WHERE path = ?";
+        
+        List<Node> nodes = jdbcTemplate.query(conn -> {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, path);
+            return ps;
+        }, (row, index) -> {
+            return getNodeFromResultSet(row);
+        });    
+
+        if (nodes.isEmpty()) {
+            return Optional.empty();
+        }
+
+        // Query returns the node (can be container or data)
+        Node node = nodes.get(0);
+
+        return Optional.of(node);
+        
+    }
+    
+    
+    
+    
     private String getFirstLevelChildrenSelector(String path) {
         String select = "(SELECT path FROM node WHERE node_id = (SELECT node_id FROM node_vos_path WHERE vos_path = ?))::varchar || '";
 
@@ -322,17 +414,112 @@ public class NodeDAO {
         return null;
     }
 
-    private List<View> getViews(Array array) throws SQLException {
+    private List<View> getViews(Array array) {
         if (array == null) {
             return null;
         }
-        return Arrays.stream((String[]) array.getArray())
+        try {
+            return Arrays.stream((String[]) array.getArray())
                 .map(uri -> {
                     View view = new View();
                     view.setUri(uri);
                     return view;
                 })
                 .collect(Collectors.toList());
+        } catch (SQLException ex) {
+            throw new RuntimeException(ex);
+        }
+        
+    }
+
+    
+    private boolean checkIfViewsAreEquals(List<View> viewsA, List<View> viewsB) {
+        
+        boolean viewsAreEqual = true;
+        if ((viewsA == null || viewsA.isEmpty()) &&
+                (viewsB == null || viewsB.isEmpty()))
+            return true;
+        
+        if ((viewsA == null || viewsA.isEmpty()) ||
+                (viewsB == null || viewsB.isEmpty()))
+            return false;
+        
+        if( viewsA.size() != viewsB.size())
+            return false;
+        
+        for(int i = 0; i < viewsA.size(); i++) {
+            String viewUriA = viewsA.get(i).getUri();
+            boolean found = false;
+            for(int j = 0; j < viewsB.size(); j++) {
+                String viewUriB = viewsB.get(i).getUri();            
+                if (viewUriA.compareTo(viewUriB) == 0) {
+                    found = true;
+                }
+            }
+            
+            if(found == false) {
+                viewsAreEqual = false;
+                break;
+            }
+        }
+        
+        return viewsAreEqual;
+        
+    }
+    
+    
+    private List<View> getAcceptedViewsFromDB(String nodePath) {
+        
+        return getViewsFromDB(nodePath, "accept_views");
+        
+    }
+    
+    
+    private List<View> getProvidedViewsFromDB(String nodePath) {
+        
+        return getViewsFromDB(nodePath, "provide_views");
+        
+    }
+    
+    
+    private List<View> getViewsFromDB(String nodePath, String viewType) {
+        
+        String sql = "SELECT accept_views FROM node WHERE node_id = "
+                + "(SELECT node_id FROM node_vos_path WHERE vos_path = ?)";
+
+        Array results = jdbcTemplate.query(sql, ps -> {
+            ps.setString(1, nodePath);
+        }, (rs) -> {
+            if(rs.next())
+                return rs.getArray("accept_views");
+            else 
+                return null;
+        });
+        
+        return getViews(results);
+          
+    }
+    
+          
+    private List<NodePaths> getNodePathsFromDB(String nodeURI) {        
+        
+        //String nodeURI = myNode.getUri();
+        String path = nodeURI.replaceAll("vos://[^/]+", "");
+        String parentPath = NodeUtils.getParentPath(path);
+
+        String sql = "SELECT path, relative_path from "
+                + "node n join node_vos_path p on n.node_id = p.node_id "
+                + "where p.vos_path = ?";
+
+        List<NodePaths> paths = jdbcTemplate.query(conn -> {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, parentPath);
+            return ps;
+        }, (row, index) -> {
+            return getPathsFromResultSet(row);
+        });
+    
+        return paths;
     }
 
     private class NodePaths {
@@ -350,5 +537,14 @@ public class NodeDAO {
         public String toString() {
             return relativePath + " " + path;
         }
+        
+        public String getPath() {
+            return this.path;
+        } 
+        
+        public String getRelativePath() {
+            return this.relativePath;
+        } 
+        
     }
 }