docs: function (sectionId, space, geometry, app) {
          let commands = [];
          let oldURL = null;
          let oldOpacity = null;
          let section = server.state.get('sections[' + sectionId + ']');
          if (section.app) {
              oldURL = section.app.url;
              oldOpacity = section.app.opacity;
              log.debug('Deleting existing application configuration');
              delete section.app;
              commands.push(JSON.stringify({ appId: Constants.APP_NAME, message: { action: Constants.Action.UPDATE, id: parseInt(sectionId, 10) } }));
          }
  
          let needsUpdate = false;
          if (space && !Object.keys(section.spaces).includes(space)) {
              log.debug('Changing space name to:', space);
              needsUpdate = true;
          }
          if (geometry.w !== undefined && geometry.w !== section.w) {
              log.debug('Changing space width to:', geometry.w);
              section.w = geometry.w;
              needsUpdate = true;
          }
          if (geometry.h !== undefined && geometry.h !== section.h) {
              log.debug('Changing space height to:', geometry.h);
              section.h = geometry.h;
              needsUpdate = true;
          }
  
          const spaceName = space || Object.keys(section.spaces)[0];
          if (geometry.x !== undefined && geometry.y !== undefined) {
              const layout = _calculateSectionLayout(spaceName, {
                  x: geometry.x, y: geometry.y, w: section.w, h: section.h
              });
              if (!needsUpdate && !Utils.JSON.equals(section.spaces[spaceName], layout)) {
                  section.x = geometry.x;
                  section.y = geometry.y;
                  needsUpdate = true;
              }
              if (needsUpdate) {
                  log.debug('Updating spaces configuration of section');
                  delete section.spaces;
                  section.spaces = {};
                  section.spaces[spaceName] = layout;
                  commands.push(JSON.stringify({ appId: Constants.APP_NAME, message: { action: Constants.Action.UPDATE, id: parseInt(sectionId, 10), spaces: section.spaces } }));
              }
          }
  
          if (app) {
              const url = app.url.replace(/\/$/, '');
              needsUpdate = needsUpdate || (url !== oldURL);
              if (oldURL && (url !== oldURL)) {
                  log.debug('Flushing application at URL:', oldURL);
                  request.post(oldURL + '/instances/' + sectionId + '/flush', _handleRequestError);
              }
              section.app = { 'url': url };
              log.debug('Got URL for app:', url);
              if (app.states) {
                  /* istanbul ignore else */
                  // DEBUG logging is turned on by default, and only turned off in production deployments.
                  // The operation of the Constants.Logging.DEBUG flag has been tested elsewhere.
                  if (Constants.Logging.DEBUG) {
                      log.debug('Got state configuration for app:', JSON.stringify(app.states));
                  }
                  // Cache or load states if they were provided as a part of the update request.
                  if (app.states.cache) {
                      Object.keys(app.states.cache).forEach(function (name) {
                          log.debug('Caching new named state for future use:', name);
                          request.post(section.app.url + '/states/' + name, {
                              headers: { 'Content-Type': Constants.HTTP_CONTENT_TYPE_JSON },
                              json: app.states.cache[name]
                          }, _handleRequestError);
                      });
                      needsUpdate = true;
                  }
                  if (app.states.load) {
                      // Either a named state or an in-line state configuration can be loaded.
                      if (typeof app.states.load === 'string' || app.states.load instanceof String) {
                          section.app.state = app.states.load;
                          log.debug('Loading existing named state:', section.app.state);
                      } else {
                          log.debug('Loading state configuration');
                          request.post(section.app.url + '/instances/' + sectionId + '/state', {
                              headers: { 'Content-Type': Constants.HTTP_CONTENT_TYPE_JSON },
                              json: app.states.load
                          }, _handleRequestError);
                      }
                      needsUpdate = true;
                  }
              }
              const opacity = app.opacity;
              if (opacity) {
                  log.debug('Setting opacity for app:', opacity);
                  section.app.opacity = opacity;
                  if (oldOpacity !== opacity && !needsUpdate) {
                      needsUpdate = true;
                  }
              }
              // If nothing changed, there is no point in making an update.
              if (needsUpdate) {
                  let $app = { 'url': section.app.url };
                  if (opacity) {
                      $app.opacity = opacity;
                  }
                  commands.push(JSON.stringify({ appId: Constants.APP_NAME, message: { action: Constants.Action.UPDATE, id: parseInt(sectionId, 10), app: $app } }));
              } else {
                  // There is no need to check if the old url was set, because, if it was not, needsUpdate would be true anyway.
                  // Removes the first update command.
                  commands.shift();
              }
          } else if (oldURL) {
              log.debug('Flushing application at URL:', oldURL);
              request.post(oldURL + '/instances/' + sectionId + '/flush', _handleRequestError);
          }
  
          // Notify OVE viewers/controllers
          server.wss.clients.forEach(function (c) {
              if (c.readyState === Constants.WEBSOCKET_READY) {
                  commands.forEach(function (m) {
                      c.safeSend(m);
                  });
              }
          });
          server.state.set('sections[' + sectionId + ']', section);
      }