Determines whether we've already registered path-param middleware for the given parameter.

@param   {string}    paramName
@returns {boolean}
327616
function alreadyRegistered (paramName) {
    let params = router.params;
    if (!params && router._router) {
      params = router._router.params;
    }

    return params && params[paramName] &&
      (params[paramName].indexOf(pathParamMiddleware) >= 0);
  }
242639
function doesPathExist(pathToVerify) {
    let pathExists = true;

    try {
        fs.accessSync(pathToVerify);
    } catch (error) {
        pathExists = false;
    }

    return pathExists;
}
449868
function checkPath(name, path) {
      helpers.exists(path, function (exist) {
        if (!exist) {
          callback(new Error(name + ' was not found (' + path + ')')); return;
        }
        progress.set(name);
      });
    }
1104249
public boolean getParamBoolean(String paramName) {
        Object paramValue = getParam(paramName);
        if (paramValue == null) {
            return false;
        }
        return Boolean.parseBoolean(paramValue.toString());
    }
622498
private static boolean registerURIPatternPath(String name, int port,
			RequestHandler handler,	RequestMapper mapper) {
		Matcher m = null;
		m = URI_PATTERN.matcher(name);
		
		if (m.matches()) {
			String host = m.group(2);
			String portString = m.group(3);
			
			if ((portString != null) && portString.startsWith(":")) {
				port = Integer.parseInt(portString.substring(1));
			}
			
			String path = m.group(4);
			
			mapper.addRequestHandler(port, null, path, handler);
			return true;
		}
		return false;
	}
106488
function (routerMiddelware) {
		var middlewareFilename = routerMiddelware.split('.')[0];
		var middlewareFunction = routerMiddelware.split('.')[1];

		return this.middlewares[middlewareFilename][middlewareFunction];
	}
1278698
public boolean endsWith(Name name) {
		DistinguishedName path = null;
		if (name instanceof DistinguishedName) {
			path = (DistinguishedName) name;
		}
		else {
			return false;
		}

		List shortlist = path.getNames();

		// this path must be at least as long
		if (getNames().size() < shortlist.size()) {
            return false;
        }

		// must have names
		if (shortlist.size() == 0) {
            return false;
        }

		ListIterator longiter = getNames().listIterator(getNames().size());
		ListIterator shortiter = shortlist.listIterator(shortlist.size());

		while (shortiter.hasPrevious()) {
			LdapRdn longname = (LdapRdn) longiter.previous();
			LdapRdn shortname = (LdapRdn) shortiter.previous();

			if (!longname.equals(shortname))
				return false;
		}

		// if short list ended, all were equal
		return true;

	}
1248453
function paramsFromStringPath(path, paramsObj) {
        //Get all the parameter names from the path.
        var elements = path.split('/');
        var params = elements.reduce(function(params, element) {
            if (element.charAt(0) === ':') {
                var paramName = element.slice(1);
                params.push(paramsObj[paramName]);
            }
            return params;
        }, []);
        return params;
    }
1204484
@Route(method = HttpMethod.GET, uri = "")
    public Result index(@PathParameter("name") String name) {
        if(names.contains(name)){
            return ok(render(template,"source",RAML_ASSET_DIR+name+RAML_EXT));
        }
        return notFound();
    }
183441
private static boolean isSameNodeAndServer(ObjectName mName) {
        String processName = mName.getKeyProperty("process");
        String nodeName = mName.getKeyProperty("node");

        if (tc.isDebugEnabled())
            Tr.debug(tc, "isSameNodeAndServer: " + mName.toString());

        if (processName != null && !processName.equals(PmiRegistry.serverName)) {
            // print only when debug is enabled since customers get worried seeing this message
            if (tc.isDebugEnabled())
                Tr.warning(tc, "PMI0002W", mName.toString() + ", expected process name is " + PmiRegistry.serverName);
            return false;
        }
        if (nodeName != null && !nodeName.equals(PmiRegistry.nodeName)) {
            // print only when debug is enabled since customers get worried seeing this message
            if (tc.isDebugEnabled())
                Tr.warning(tc, "PMI0002W", mName.toString() + ", expected node name is " + PmiRegistry.nodeName);
            return false;
        }

        return true;
    }
1308493
function(methodName, args) {
        var method   = this.spec.methods[methodName];
        if (method.deprecated === true)
            console.warn('Method '+ methodName + ' is deprecated.')
        var callback = args.pop(); // callback is always at the end
        var middleware = args[0];
        var params   = null;
        var payload  = null;
        var index = 0;
        if (typeof middleware != 'function') {
            params = args[0];
            middleware = null;
        } else {
            params = args[1];
            index = 1;
        }
        if (args.length > 1) {
            payload = args[index + 1];
        } else {
            if (method.required_params.length == 0
                && method.optional_params.length == 0) {
                payload = args[index];
                params = null;
            }
        }
        if (this._isValidCall(method, callback, params, payload)) {
            var request = this._createRequest(method, params, payload);
            var middlewares = this.middlewares.slice(0);
            if (middleware !== null) middlewares.push({cond: function() { return true; }, fun: middleware});
            this._callRequestMiddlewares(middlewares, method, request, [], callback);
        }
    }
1028669
private boolean verifyProvide(Node methodName, Node arg) {
    if (!verifyLastArgumentIsString(methodName, arg)) {
      return false;
    }

    if (!NodeUtil.isValidQualifiedName(
        compiler.getOptions().getLanguageIn().toFeatureSet(), arg.getString())) {
      compiler.report(
          JSError.make(
              arg,
              INVALID_PROVIDE_ERROR,
              arg.getString(),
              compiler.getOptions().getLanguageIn().toString()));
      return false;
    }

    return true;
  }
362444
function createAPI(app, mountPath, middlewareOpts) {
    var router = express.Router(),
        apiDocumentationMountPoint = '/developer/api',
        logger = middlewareOpts.logger.fork('api'),
        gmeAuth = middlewareOpts.gmeAuth,
        metadataStorage = gmeAuth.metadataStorage,
        authorizer = gmeAuth.authorizer,
        safeStorage = middlewareOpts.safeStorage,
        ensureAuthenticated = middlewareOpts.ensureAuthenticated,
        gmeConfig = middlewareOpts.gmeConfig,
        getUserId = middlewareOpts.getUserId,
        STORAGE_CONSTANTS = CONSTANTS.STORAGE,
        CORE_CONSTANTS = CONSTANTS.CORE,
        versionedAPIPath = mountPath + '/v1',
        latestAPIPath = mountPath,
        registerEndPoint = typeof gmeConfig.authentication.allowUserRegistration === 'string' ?
            require(gmeConfig.authentication.allowUserRegistration)(middlewareOpts) :
            require('./defaultRegisterEndPoint')(middlewareOpts),
        seedToBlobHash = {},
        paths;

    app.get(apiDocumentationMountPoint, function (req, res) {
        res.sendFile(path.join(__dirname, '..', '..', '..', 'docs', 'REST', 'index.html'));
    });

    function getFullUrl(req, name) {
        return req.protocol + '://' + req.headers.host + middlewareOpts.getMountedPath(req) + req.baseUrl + name;
    }

    function getNewJWToken(userId, callback) {
        var deferred = Q.defer();

        if (gmeConfig.authentication.enable === true) {
            gmeAuth.generateJWTokenForAuthenticatedUser(userId)
                .then(deferred.resolve)
                .catch(deferred.reject);
        } else {
            deferred.resolve();
        }

        return deferred.promise.nodeify(callback);
    }

    function exportProject(req, res) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                req.params.projectName),
            workerParameters = {

                command: CONSTANTS.SERVER_WORKER_REQUESTS.EXPORT_PROJECT_TO_FILE,
                projectId: projectId,
                branchName: req.params.branchId || null,
                commitHash: req.params.commitHash ? StorageUtil.getHashTaggedHash(req.params.commitHash) : null,
                tagName: req.params.tagId || null,
                withAssets: true
            };

        getNewJWToken(userId)
            .then(function (token) {
                workerParameters.webgmeToken = token;
                return Q.ninvoke(middlewareOpts.workerManager, 'request', workerParameters);
            })
            .then(function (result) {
                res.redirect(result.downloadUrl);
                return;
            })
            .catch(function (err) {
                logger.error('Cannot handle export request', err);
                res.status(403).send('Cannot process request: ' + err);
            });
    }

    function exportModel(req, res) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                req.params.projectName),
            workerParameters = {
                command: CONSTANTS.SERVER_WORKER_REQUESTS.EXPORT_SELECTION_TO_FILE,
                projectId: projectId,
                branchName: req.params.branchId || null,
                commitHash: req.params.commitHash ? StorageUtil.getHashTaggedHash(req.params.commitHash) : null,
                tagName: req.params.tagId || null,
                paths: ['/' + req.params[0]],
                withAssets: true
            };

        getNewJWToken(userId)
            .then(function (token) {
                workerParameters.webgmeToken = token;

                return Q.ninvoke(middlewareOpts.workerManager, 'request', workerParameters);
            })
            .then(function (result) {
                res.redirect(result.downloadUrl);
                return;
            })
            .catch(function (err) {
                logger.error('Cannot handle export request', err);
                res.status(403).send('Cannot process request: ' + err);
            });
    }

    // ensure authenticated can be used only after this rule
    router.use('*', function (req, res, next) {
        // TODO: set all headers, check rate limit, etc.
        res.setHeader('X-WebGME-Media-Type', 'webgme.v1');
        next();
    });

    router.post('/register', registerEndPoint);

    // modifications are allowed only if the user is authenticated
    // all get rules by default do NOT require authentication, if the get rule has to be protected add inline
    // the ensureAuthenticated function middleware
    router.post('*', ensureAuthenticated);
    router.put('*', ensureAuthenticated);
    router.patch('*', ensureAuthenticated);
    router.delete('*', ensureAuthenticated);

    router.get('/', function (req, res/*, next*/) {
        res.json({
            current_user_url: getFullUrl(req, '/user'),
            organization_url: getFullUrl(req, '/orgs/{org}'),
            project_url: getFullUrl(req, '/projects/{owner}/{project}'),
            user_url: getFullUrl(req, '/users/{user}'),
            api_documentation_url: req.protocol + '://' + req.headers.host + apiDocumentationMountPoint,
            source_code_documentation_url: req.protocol + '://' + req.headers.host + '/docs/source/index.html'
        });
    });

    function putUser(receivedData, req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (data) {

                if (!data.siteAdmin) {
                    res.status(403);
                    throw new Error('site admin role is required for this operation');
                }

                gmeAuth.addUser(receivedData.userId,
                    receivedData.email,
                    receivedData.password,
                    receivedData.canCreate === 'true' || receivedData.canCreate === true,
                    {overwrite: receivedData.overwrite})
                    .then(function (newData) {
                        res.json(newData);
                    })
                    .catch(function (err) {
                        res.status(400);
                        next(err);
                    });
            })
            .catch(next);
    }

    function ensureSameUserOrSiteAdmin(req, res) {
        var userId = getUserId(req);

        return gmeAuth.getUser(userId)
            .then(function (userData) {
                if (userData.siteAdmin || userId === req.params.username) {
                    return userData;
                } else {
                    res.status(403);
                    throw new Error('site admin role is required for this operation');
                }
            });
    }

    /**
     * @param req
     * @param res
     * @param callback
     * @returns {*}
     */
    function getUserEntry(req, res, callback) {
        var deferred = Q.defer(),
            userId = getUserId(req),
            query = {disabled: undefined};

        gmeAuth.getUser(userId, query)
            .then(function (userData) {
                if (userData.disabled === true) {
                    res.clearCookie(gmeConfig.authentication.jwt.cookieId);
                    res.status(401);
                    deferred.reject(new Error('user has been disabled [' + userId + ']'));
                } else {
                    deferred.resolve(userData);
                }
            })
            .catch(deferred.reject);

        return deferred.promise.nodeify(callback);
    }

    function filterUsersOrOrgs(userData, projects, usersOrOrgs) {
        var result = [],
            readableProjects = {},
            filteredData,
            i;

        function getFilteredData(data) {
            var filteredProjects = {};
            data = usersOrOrgs[i];

            if (userData._id === data._id) {
                return userData;
            } else if (userData.siteAdmin === true) {
                return data;
            } else {
                if (data.type === 'Organization') {
                    if (userData._id === gmeConfig.authentication.guestAccount &&
                        data.users.indexOf(userData._id) === -1) {
                        // The guest can only view organization where he/she is a member.
                        return;
                    }
                } else {
                    // Clear out user-data.
                    data.settings = {};
                    data.data = {};
                    data.email = '';
                    data.siteAdmin = false;
                    data.canCreate = false;
                }

                // We only return project info for projects the requesting user has access to.
                Object.keys(data.projects).forEach(function (projectId) {
                    if (readableProjects[projectId]) {
                        filteredProjects[projectId] = data.projects[projectId];
                    }
                });

                data.projects = filteredProjects;

                return data;
            }
        }

        projects.forEach(function (pData) {
            readableProjects[pData._id] = true;
        });

        for (i = 0; i < usersOrOrgs.length; i += 1) {
            filteredData = getFilteredData(usersOrOrgs[i]);
            if (filteredData) {
                result.push(filteredData);
            }
        }

        return result;
    }

    // AUTHENTICATED
    router.get('/user', ensureAuthenticated, function (req, res, next) {
        getUserEntry(req, res)
            .then(function (data) {
                res.json(data);
            })
            .catch(next);
    });

    // Example: curl -i -H "Content-Type: application/json" -X PATCH
    //  -d "{\"email\":\"asdf@alkfm.com\",\"canCreate\":false}" http://demo:demo@127.0.0.1:8888/api/v1/user
    router.patch('/user', function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {
                var receivedData = req.body;

                if (userData.siteAdmin !== true &&
                    (receivedData.hasOwnProperty('siteAdmin') || receivedData.hasOwnProperty('canCreate'))) {
                    res.status(403);
                    throw new Error('setting siteAdmin and/or canCreate property requires site admin role');
                }

                return gmeAuth.updateUser(userId, receivedData);
            })
            .then(function (newData) {
                res.json(newData);
            })
            .catch(next);
    });

    router.delete('/user', function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.deleteUser(userId, false)
            .then(function () {
                res.sendStatus(204);
            })
            .catch(next);
    });

    router.get('/user/data', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {
                res.json(userData.data);
            })
            .catch(next);
    });

    router.put('/user/data', function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.updateUserDataField(userId, req.body, true)
            .then(function (data) {
                res.json(data);
            })
            .catch(next);
    });

    router.patch('/user/data', function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.updateUserDataField(userId, req.body)
            .then(function (data) {
                res.json(data);
            })
            .catch(next);
    });

    router.delete('/user/data', function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.updateUserDataField(userId, {}, true)
            .then(function (/*data*/) {
                res.sendStatus(204);
            })
            .catch(next);
    });

    router.get('/user/token', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        if (gmeConfig.authentication.enable === false) {
            res.status(404);
            res.json({
                message: 'Authentication is turned off',
            });
            return;
        }

        if (req.userData.token && req.userData.newToken === true) {
            res.status(200);
            res.json({
                webgmeToken: req.userData.token
            });
        } else {
            getNewJWToken(userId)
                .then(function (token) {
                    res.status(200);
                    res.json({webgmeToken: token});
                })
                .catch(function (err) {
                    next(err);
                });
        }
    });

    router.get('/componentSettings', ensureAuthenticated, function (req, res, next) {
        webgmeUtils.getComponentsJson(logger)
            .then(function (componentsJson) {
                res.json(componentsJson);
            })
            .catch(next);
    });

    router.get('/componentSettings/:componentId', ensureAuthenticated, function (req, res, next) {
        webgmeUtils.getComponentsJson(logger)
            .then(function (componentsJson) {
                res.json(componentsJson[req.params.componentId] || {});
            })
            .catch(next);
    });

    router.get('/user/settings', ensureAuthenticated, function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                res.json(userData.settings || {});
            })
            .catch(next);
    });

    router.put('/user/settings', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserSettings(userData._id, req.body, true);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(next);
    });

    router.patch('/user/settings', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserSettings(userData._id, req.body);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(next);
    });

    router.delete('/user/settings', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserSettings(userData._id, {}, true);
            })
            .then(function (/*settings*/) {
                res.sendStatus(204);
            })
            .catch(next);
    });

    router.get('/user/settings/:componentId', ensureAuthenticated, function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                res.json(userData.settings[req.params.componentId] || {});
            })
            .catch(next);
    });

    router.put('/user/settings/:componentId', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserComponentSettings(userData._id, req.params.componentId, req.body, true);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(next);
    });

    router.patch('/user/settings/:componentId', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserComponentSettings(userData._id, req.params.componentId, req.body);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(next);
    });

    router.delete('/user/settings/:componentId', function (req, res, next) {
        getUserEntry(req, res)
            .then(function (userData) {
                return gmeAuth.updateUserComponentSettings(userData._id, req.params.componentId, {}, true);
            })
            .then(function (/*settings*/) {
                res.sendStatus(204);
            })
            .catch(next);
    });

    router.get('/users', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            userData,
            query,
            projection;

        if (req.query.displayName) {
            gmeAuth.listUsers({displayName: {$type: 2}}, {displayName: 1})
                .then(function (result) {
                    res.json(result);
                })
                .catch(next);
        } else {
            gmeAuth.getUser(userId)
                .then(function (userData_) {
                    var doGetProjects = userId !== gmeConfig.authentication.guestAccount && !userData_.siteAdmin;
                    userData = userData_;

                    if (req.query.includeDisabled && userData.siteAdmin) {
                        query = {disabled: undefined};
                    }

                    if (userId === gmeConfig.authentication.guestAccount) {
                        query = {_id: userId};
                    } else if (!userData.siteAdmin) {
                        projection = {
                            data: 0,
                            settings: 0,
                            email: 0,
                            password: 0
                        };
                    }

                    return Q.all([
                        doGetProjects ? safeStorage.getProjects({username: userId}) : Q.resolve([]),
                        gmeAuth.listUsers(query, projection)
                    ]);
                })
                .then(function (results) {
                    res.json(filterUsersOrOrgs(userData, results[0], results[1]));
                })
                .catch(next);
        }
    });

    router.put('/users', function (req, res, next) {

        //"userId: "newUser"
        //"email": "user@example.com",
        //"password": "pass",
        //"canCreate": null,

        putUser(req.body, req, res, next);
    });

    router.get('/users/:username', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {
                if (userId === req.params.username) {
                    return Q.resolve(userData);
                } else if (userId === gmeConfig.authentication.guestAccount) {
                    res.status(404);
                    return Q.reject(new Error('no such user'));
                } else {
                    return Q.all([
                        userData.siteAdmin ? [] : safeStorage.getProjects({username: userId}),
                        gmeAuth.getUser(req.params.username)
                    ])
                        .then(function (results) {
                            return filterUsersOrOrgs(userData, results[0], [results[1]])[0];
                        });
                }
            })
            .then(function (data) {
                res.json(data);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.put('/users/:username', function (req, res, next) {
        var receivedData = {
            userId: req.params.username,
            email: req.body.email,
            password: req.body.password,
            canCreate: req.body.canCreate || false,
            data: req.body.data || {},
            overwrite: req.body.overwrite
        };

        putUser(receivedData, req, res, next);
    });

    router.patch('/users/:username', function (req, res, next) {
        // body params
        //"email": "user@example.com",
        //"password": "pass",
        //"canCreate": null,
        //"siteAdmin": false,
        //"disabled": false, // Only applicable if false -> will re-enable user
        //"data": {}
        ensureSameUserOrSiteAdmin(req, res)
            .then(function (userData) {
                if (userData.siteAdmin !== true &&
                    (req.body.hasOwnProperty('siteAdmin') || req.body.hasOwnProperty('canCreate'))) {
                    res.status(403);
                    throw new Error('setting siteAdmin and/or canCreate property requires site admin role');
                }

                if (req.body.hasOwnProperty('disabled') && req.body.disabled === false) {
                    if (userData.siteAdmin === true) {
                        return gmeAuth.reEnableUser(req.params.username);
                    } else {
                        res.status(403);
                        throw new Error('re-enabling users requires site admin role');
                    }
                } else {
                    return gmeAuth.updateUser(req.params.username, req.body);
                }
            })
            .then(function (userData) {
                res.json(userData);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    //TODO: why is this 400 and not 404?
                    res.status(400);
                }

                next(err);
            });
    });

    router.delete('/users/:username', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function (userData) {
                var force = req.query.force && userData.siteAdmin === true;
                return gmeAuth.deleteUser(req.params.username, force);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user') > -1) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.get('/users/:username/data', ensureAuthenticated, function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.getUser(req.params.username);
            })
            .then(function (userData) {
                res.json(userData.data);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.put('/users/:username/data', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserDataField(req.params.username, req.body, true);
            })
            .then(function (data) {
                res.json(data);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.patch('/users/:username/data', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserDataField(req.params.username, req.body);
            })
            .then(function (data) {
                res.json(data);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.delete('/users/:username/data', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserDataField(req.params.username, {}, true);
            })
            .then(function (/*userData*/) {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.get('/users/:username/settings', ensureAuthenticated, function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.getUser(req.params.username);
            })
            .then(function (userData) {
                res.json(userData.settings);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.put('/users/:username/settings', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserSettings(req.params.username, req.body, true);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.patch('/users/:username/settings', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserSettings(req.params.username, req.body);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.delete('/users/:username/settings', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserSettings(req.params.username, {}, true);
            })
            .then(function (/*settings*/) {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.get('/users/:username/settings/:componentId', ensureAuthenticated, function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.getUser(req.params.username);
            })
            .then(function (userData) {
                res.json(userData.settings[req.params.componentId] || {});
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.put('/users/:username/settings/:componentId', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserComponentSettings(req.params.username, req.params.componentId, req.body, true);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.patch('/users/:username/settings/:componentId', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserComponentSettings(req.params.username, req.params.componentId, req.body);
            })
            .then(function (settings) {
                res.json(settings);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.delete('/users/:username/settings/:componentId', function (req, res, next) {
        ensureSameUserOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.updateUserComponentSettings(req.params.username, req.params.componentId, {}, true);
            })
            .then(function (/*settings*/) {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user [' + req.params.username) === 0) {
                    res.status(404);
                }

                next(err);
            });
    });

    //ORGANIZATIONS
    function ensureOrgOrSiteAdmin(req, res) {
        var userId = getUserId(req),
            userData;

        return gmeAuth.getUser(userId)
            .then(function (data) {
                userData = data;
                return gmeAuth.getAdminsInOrganization(req.params.orgId);
            })
            .then(function (admins) {
                if (!userData.siteAdmin && admins.indexOf(userId) === -1) {
                    res.status(403);
                    throw new Error('site admin role or organization admin is required for this operation');
                }

                return userData;
            });
    }

    router.get('/orgs', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            userData,
            query;

        gmeAuth.getUser(userId)
            .then(function (userData_) {
                userData = userData_;
                if (req.query.includeDisabled && userData.siteAdmin) {
                    query = {disabled: undefined};
                }

                return Q.all([
                    safeStorage.getProjects({username: userId}),
                    gmeAuth.listOrganizations(query)
                ]);
            })
            .then(function (results) {
                res.json(filterUsersOrOrgs(userData, results[0], results[1]));
            })
            .catch(next);
    });

    router.put('/orgs/:orgId', function (req, res, next) {

        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (data) {
                if (!(data.siteAdmin || data.canCreate)) {
                    res.status(403);
                    throw new Error('site admin role or can create is required for this operation');
                }

                return gmeAuth.addOrganization(req.params.orgId, req.body.info);
            })
            .then(function () {
                return gmeAuth.setAdminForUserInOrganization(userId, req.params.orgId, true);
            })
            .then(function () {
                return gmeAuth.addUserToOrganization(userId, req.params.orgId);
            })
            .then(function () {
                return gmeAuth.getOrganization(req.params.orgId);
            })
            .then(function (orgData) {
                res.json(orgData);
            })
            .catch(function (err) {
                if (err.message.indexOf('user or org already exists') > -1) {
                    res.status(400);
                }

                next(err);
            });
    });

    router.get('/orgs/:orgId', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {

                return Q.all([
                    userData.siteAdmin ? [] : safeStorage.getProjects({username: userId}),
                    gmeAuth.getOrganization(req.params.orgId)
                ])
                    .then(function (results) {
                        return filterUsersOrOrgs(userData, results[0], [results[1]])[0];
                    });
            })
            .then(function (orgData) {
                if (!orgData) {
                    // This is the case where the guest is not a member.
                    throw new Error('no such organization [');
                }

                res.json(orgData);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.patch('/orgs/:orgId', function (req, res, next) {
        // body params
        //"info": {}
        //"disabled": false, // Only applicable if false -> will re-enable org
        function updateOrg() {
            var userId;
            if (req.body.hasOwnProperty('disabled') && req.body.disabled === false) {
                userId = getUserId(req);
                return gmeAuth.getUser(userId)
                    .then(function (userData) {
                        if (userData.siteAdmin === true) {
                            return gmeAuth.reEnableOrganization(req.params.orgId);
                        } else {
                            res.status(403);
                            throw new Error('re-enabling organizations requires site admin role');
                        }
                    });
            } else {
                return ensureOrgOrSiteAdmin(req, res)
                    .then(function () {
                        return gmeAuth.updateOrganizationInfo(req.params.orgId, req.body.info);
                    });
            }
        }

        updateOrg()
            .then(function (orgData) {
                res.json(orgData);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [' + req.params.orgId) === 0 ||
                    err.message.indexOf('info is not an object') > -1) {
                    res.status(400);
                }

                next(err);
            });
    });

    router.delete('/orgs/:orgId', function (req, res, next) {
        function deleteOrg() {
            var userId;
            if (req.query.force) {
                userId = getUserId(req);
                return gmeAuth.getUser(userId)
                    .then(function (userData) {
                        if (userData.siteAdmin === true) {
                            return gmeAuth.removeOrganizationByOrgId(req.params.orgId, true);
                        } else {
                            res.status(403);
                            throw new Error('force deletion requires site admin role');
                        }
                    });
            } else {
                return ensureOrgOrSiteAdmin(req, res)
                    .then(function () {
                        return gmeAuth.removeOrganizationByOrgId(req.params.orgId, req.body.info);
                    });
            }
        }

        deleteOrg(req, res)
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.put('/orgs/:orgId/users/:username', function (req, res, next) {
        ensureOrgOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.addUserToOrganization(req.params.username, req.params.orgId);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1 ||
                    err.message.indexOf('no such user [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.delete('/orgs/:orgId/users/:username', function (req, res, next) {
        ensureOrgOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.removeUserFromOrganization(req.params.username, req.params.orgId);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.put('/orgs/:orgId/admins/:username', function (req, res, next) {
        ensureOrgOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.setAdminForUserInOrganization(req.params.username, req.params.orgId, true);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1 ||
                    err.message.indexOf('no such user [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.delete('/orgs/:orgId/admins/:username', function (req, res, next) {
        ensureOrgOrSiteAdmin(req, res)
            .then(function () {
                return gmeAuth.setAdminForUserInOrganization(req.params.username, req.params.orgId, false);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such organization [') > -1 ||
                    err.message.indexOf('no such user [') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    // PROJECTS

    function loadNodePathByCommitHash(userId, projectId, commitHash, path) {
        var getCommitParams = {
            username: userId,
            projectId: projectId,
            number: 1,
            before: commitHash
        };

        return safeStorage.getCommits(getCommitParams)
            .then(function (commits) {
                var loadPathsParams = {
                    projectId: projectId,
                    username: userId,
                    pathsInfo: [
                        {
                            parentHash: commits[0].root,
                            path: path
                        }
                    ],
                    excludeParents: true
                };

                return safeStorage.loadPaths(loadPathsParams);
            })
            .then(function (dataObjects) {
                var hashes = Object.keys(dataObjects),
                    dataObj,
                    newOvr,
                    relid,
                    hash,
                    ovrPath;

                if (hashes.length === 1) {
                    return dataObjects[hashes[0]];
                } else if (hashes.length === 0) {
                    throw new Error('Path does not exist ' + path);
                } else {
                    // There are multiple hashes -> the overlay is shared so build up the complete object
                    for (hash in dataObjects) {
                        if (dataObjects[hash].type !== STORAGE_CONSTANTS.OVERLAY_SHARD_TYPE) {
                            dataObj = dataObjects[hash];
                            break;
                        }
                    }

                    if (!dataObj) {
                        throw new Error('loadPaths did not return with a dataObj hash, only shards');
                    } else if (!dataObj.ovr || Object.keys(dataObj.ovr) === 0) {
                        throw new Error('loadPaths returned with multiple objects but missing or empty ovr..');
                    }

                    newOvr = {};
                    for (relid in dataObj.ovr) {
                        if (relid !== CORE_CONSTANTS.OVERLAY_SHARD_INDICATOR) {
                            hash = dataObj.ovr[relid];
                            if (dataObjects[hash] && dataObjects[hash].type === STORAGE_CONSTANTS.OVERLAY_SHARD_TYPE) {
                                for (ovrPath in dataObjects[hash].items) {
                                    newOvr[ovrPath] = dataObjects[hash].items[ovrPath];
                                }
                            } else {
                                logger.error('Did not find shard for overlay', hash);
                            }
                        }
                    }

                    dataObj.ovr = newOvr;

                    return dataObj;
                }
            });
    }

    function canUserAuthorizeProject(req) {
        var userId = getUserId(req);

        return gmeAuth.getUser(userId)
            .then(function (userData) {
                // Make sure user is authorized (owner, admin in owner Org or siteAdmin).
                if (userId === req.params.ownerId || userData.siteAdmin === true) {
                    return true;
                } else {
                    return gmeAuth.getOrganization(req.params.ownerId)
                        .then(function (orgData) {
                            if (orgData.admins.indexOf(userId) > -1) {
                                return true;
                            }

                            return false;
                        })
                        .catch(function (err) {
                            logger.debug(err);
                            return false;
                        });
                }
            });
    }

    router.get('/projects', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);
        safeStorage.getProjects({username: userId, info: true})
            .then(function (result) {
                res.json(result);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            data = {
                username: userId,
                projectId: projectId
            },
            branches;

        safeStorage.getBranches(data)
            .then(function (branches_) {
                branches = branches_;
                return metadataStorage.getProject(projectId);
            })
            .then(function (projectData) {
                projectData.branches = branches;
                res.json(projectData);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.patch('/projects/:ownerId/:projectName', function (req, res, next) {
        var userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            },
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName);

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {
                if (projectAccess && projectAccess.write) {
                    return;
                } else {
                    res.status(403);
                    throw new Error('Not authorized to modify project');
                }
            })
            .then(function () {
                return metadataStorage.updateProjectInfo(projectId, req.body);
            })
            .then(function (projectData) {
                res.json(projectData);
            })
            .catch(function (err) {
                next(err);
            });
    });
    /**
     * Creating project by seed
     *
     * @param {string} req.body.type - sets if the seed is coming from file (==='file') source or from some
     *  existing project(==='db').
     * @param {string} req.body.seedName - the name or rather id of the seed
     *          db - projectId
     *          seed - name of the seed-file (no extension - matches json file)
     * @param {string} [req.body.seedBranch='master'] - for 'db' optional branch name to seed from.
     * @param {string} [req.body.seedCommit] - for 'db' optional commit-hash to seed from
     * (if given seedBranch is not used).
     * @param {string} [req.body.kind] - If not given:
     *                  1) type is seed - will use kind stored in seed else name of seed.
     *                  2) type is db - will use kind stored project info.
     * @example {type:'file', seedName:'EmptyProject'}
     * @example {type:'db', seedName:'guest+aFSMProject', seedBranch:'release', kind: 'FiniteStateMachine'}
     */
    router.put('/projects/:ownerId/:projectName', function (req, res, next) {
        var userId = getUserId(req),
            command = req.body;

        command.command = 'seedProject';
        command.userId = userId;
        command.ownerId = req.params.ownerId;
        command.projectName = req.params.projectName;

        getNewJWToken(userId)
            .then(function (token) {
                command.webgmeToken = token;
                return Q.nfcall(middlewareOpts.workerManager.request, command);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                next(new Error(err));
            }); //TODO do we need special error handling???
    });

    router.delete('/projects/:ownerId/:projectName', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName)
            };

        safeStorage.deleteProject(data)
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.put('/projects/:ownerId/:projectName/authorize/:userOrOrgId/:rights', function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        canUserAuthorizeProject(req)
            .then(function (isAuthorized) {
                if (isAuthorized === false) {
                    res.status(403);
                    throw new Error('Not allowed to authorize users/organizations for project');
                }
                // ensure project exists
                return metadataStorage.getProject(projectId);
            })
            .then(function (/*projectData*/) {
                var rights = {
                    read: req.params.rights.indexOf('r') !== -1,
                    write: req.params.rights.indexOf('w') !== -1,
                    delete: req.params.rights.indexOf('d') !== -1
                };

                return authorizer.setAccessRights(req.params.userOrOrgId, projectId, rights, projectAuthParams);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user or org') > -1 || err.message.indexOf('no such project') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.delete('/projects/:ownerId/:projectName/authorize/:userOrOrgId', function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        canUserAuthorizeProject(req)
            .then(function (isAuthorized) {
                if (isAuthorized === false) {
                    res.status(403);
                    throw new Error('Not allowed to authorize users/organizations for project');
                }
                // ensure project exists
                return metadataStorage.getProject(projectId);
            })
            .then(function (/*projectData*/) {
                return authorizer.setAccessRights(req.params.userOrOrgId, projectId,
                    {read: false, write: false, delete: false}, projectAuthParams);
            })
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such user or org') > -1 || err.message.indexOf('no such project') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.post('/projects/:ownerId/:projectName/transfer/:userOrOrgId', function (req, res, next) {
        var newOwnerId = req.params.userOrOrgId,
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            data = {
                newOwnerId: newOwnerId,
                projectId: projectId,
                username: userId
            };

        safeStorage.transferProject(data)
            .then(function (newProjectId) {
                return metadataStorage.getProject(newProjectId);
            })
            .then(function (projectData) {
                res.json(projectData);
            })
            .catch(function (err) {
                if (err.message.toLowerCase().indexOf('no such') > -1) {
                    res.status(404);
                } else if (err.message.toLowerCase().indexOf('not authorized') > -1) {
                    res.status(403);
                }
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/commits', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                before: Date.now(), // current time
                number: parseInt(req.query.n, 10) || 100 // asks for the last 100 commits from the time specified above
            };

        safeStorage.getCommits(data)
            .then(function (result) {
                res.json(result);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/commits/:commitHash', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            commitHash = StorageUtil.getHashTaggedHash(req.params.commitHash),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                before: commitHash,
                number: 1
            };

        safeStorage.getCommits(data)
            .then(function (result) {
                res.json(result[0]);
            })
            .catch(function (err) {
                if (err.message.indexOf('not exist') > -1 || err.message.indexOf('Not authorized to read') > -1) {
                    err.status = 404;
                }
                next(err);
            });
    });

    paths = ['/projects/:ownerId/:projectName/commits/:commitHash/export',
        '/projects/:ownerId/:projectName/commits/:commitHash/export/*'];
    router.get(paths, ensureAuthenticated, function (req, res, next) {
        if (req.params[0] === undefined || req.params[0] === '') {
            exportProject(req, res, next);
        } else {
            exportModel(req, res, next);
        }
    });

    paths = ['/projects/:ownerId/:projectName/commits/:commitHash/tree',
        '/projects/:ownerId/:projectName/commits/:commitHash/tree/*'];
    router.get(paths, ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                req.params.projectName),
            commitHash = StorageUtil.getHashTaggedHash(req.params.commitHash);

        loadNodePathByCommitHash(userId, projectId, commitHash,
            '/' + (req.params[0] === undefined ? '' : req.params[0]))
            .then(function (nodeObj) {
                res.json(nodeObj);
            })
            .catch(function (err) {
                if (err.message.indexOf('not exist') > -1 || err.message.indexOf('Not authorized to read') > -1) {
                    err.status = 404;
                }
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/compare/:branchOrCommitA...:branchOrCommitB',
        ensureAuthenticated,
        function (req, res, next) {
            var userId = getUserId(req),
                projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                workerParameters = {
                    command: CONSTANTS.SERVER_WORKER_REQUESTS.DIFF,
                    projectId: projectId,
                    branchOrCommitA: req.params.branchOrCommitA,
                    branchOrCommitB: req.params.branchOrCommitB,
                };

            getNewJWToken(userId)
                .then(function (token) {
                    workerParameters.webgmeToken = token;
                    return Q.ninvoke(middlewareOpts.workerManager, 'request', workerParameters);
                })
                .then(function (result) {
                    res.json(result);
                })
                .catch(function (err) {
                    next(err);
                });
        });

    router.get('/projects/:ownerId/:projectName/branches', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName)
            };

        safeStorage.getBranches(data)
            .then(function (result) {
                res.json(result);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/branches/:branchId', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                branchName: req.params.branchId
            };

        safeStorage.getLatestCommitData(data)
            .then(function (result) {
                res.json(result);
            })
            .catch(function (err) {
                if (err.message.indexOf('not exist') > -1) {
                    err.status = 404;
                }
                next(err);
            });
    });

    paths = ['/projects/:ownerId/:projectName/branches/:branchId/export',
        '/projects/:ownerId/:projectName/branches/:branchId/export/*'];
    router.get(paths, ensureAuthenticated, function (req, res, next) {
        if (req.params[0] === undefined || req.params[0] === '') {
            exportProject(req, res, next);
        } else {
            exportModel(req, res, next);
        }
    });

    router.patch('/projects/:ownerId/:projectName/branches/:branchId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                branchName: req.params.branchId,
                oldHash: req.body.oldHash,
                newHash: req.body.newHash
            };

        safeStorage.setBranchHash(data)
            .then(function () {
                res.sendStatus(200);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.put('/projects/:ownerId/:projectName/branches/:branchId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                branchName: req.params.branchId,
                hash: req.body.hash
            };

        safeStorage.createBranch(data)
            .then(function () {
                res.sendStatus(201);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.delete('/projects/:ownerId/:projectName/branches/:branchId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                branchName: req.params.branchId
            };

        safeStorage.deleteBranch(data)
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/branches/:branchId/commits', ensureAuthenticated,
        function (req, res, next) {
            var userId = getUserId(req),
                data = {
                    username: userId,
                    projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                        req.params.projectName),
                    start: req.params.branchId,
                    number: parseInt(req.query.n, 10) || 100
                };

            safeStorage.getHistory(data)
                .then(function (result) {
                    res.json(result);
                })
                .catch(function (err) {
                    if (err.message.indexOf('not exist') > -1) {
                        err.status = 404;
                    }
                    next(err);
                });
        }
    );

    paths = ['/projects/:ownerId/:projectName/branches/:branchId/tree',
        '/projects/:ownerId/:projectName/branches/:branchId/tree/*'];
    router.get(paths, ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                req.params.projectName),
            data = {
                username: userId,
                projectId: projectId,
                branchName: req.params.branchId
            };

        safeStorage.getBranchHash(data)
            .then(function (branchHash) {
                if (!branchHash) {
                    throw new Error('Branch does not exist ' + req.params.branchId);
                }
                return loadNodePathByCommitHash(userId, projectId, branchHash,
                    '/' + (req.params[0] === undefined ? '' : req.params[0]));
            })
            .then(function (dataObj) {
                res.json(dataObj);
            })
            .catch(function (err) {
                if (err.message.indexOf('not exist') > -1 || err.message.indexOf('Not authorized to read') > -1) {
                    err.status = 404;
                }
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/tags', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName)
            };

        safeStorage.getTags(data)
            .then(function (result) {
                res.json(result);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/tags/:tagId', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName)
            };

        safeStorage.getTags(data)
            .then(function (result) {
                if (result.hasOwnProperty(req.params.tagId) === true) {
                    res.redirect(req.baseUrl + '/projects/' + req.params.ownerId + '/' + req.params.projectName +
                        '/commits/' + result[req.params.tagId].substring(1));
                } else {
                    res.sendStatus(404);
                }
            })
            .catch(function (err) {
                next(err);
            });
    });

    paths = ['/projects/:ownerId/:projectName/tags/:tagId/export',
        '/projects/:ownerId/:projectName/tags/:tagId/export/*'];

    router.get(paths, ensureAuthenticated, function (req, res, next) {
        if (req.params[0] === undefined || req.params[0] === '') {
            exportProject(req, res, next);
        } else {
            exportModel(req, res, next);
        }
    });

    paths = ['/projects/:ownerId/:projectName/tags/:tagId/tree',
        '/projects/:ownerId/:projectName/tags/:tagId/tree/*'];
    router.get(paths, ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                req.params.projectName),
            data = {
                username: userId,
                projectId: projectId
            };

        safeStorage.getTags(data)
            .then(function (tags) {
                if (tags.hasOwnProperty(req.params.tagId) !== true) {
                    throw new Error('Tag does not exist ' + req.params.tagId);
                }
                return loadNodePathByCommitHash(userId, projectId, tags[req.params.tagId],
                    '/' + (req.params[0] === undefined ? '' : req.params[0]));
            })
            .then(function (dataObj) {
                res.json(dataObj);
            })
            .catch(function (err) {
                if (err.message.indexOf('not exist') > -1 || err.message.indexOf('Not authorized to read') > -1) {
                    err.status = 404;
                }
                next(err);
            });
    });

    router.put('/projects/:ownerId/:projectName/tags/:tagId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                tagName: req.params.tagId,
                commitHash: req.body.hash
            };

        safeStorage.createTag(data)
            .then(function () {
                res.sendStatus(201);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.patch('/projects/:ownerId/:projectName/tags/:tagId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                tagName: req.params.tagId,
                commitHash: req.body.hash
            };

        safeStorage.deleteTag(data)
            .then(function () {
                return safeStorage.createTag(data);
            })
            .then(function () {
                res.sendStatus(200);
            })
            .catch(function (err) {
                next(err);
            });
    });

    router.delete('/projects/:ownerId/:projectName/tags/:tagId', function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                tagName: req.params.tagId
            };

        safeStorage.deleteTag(data)
            .then(function () {
                res.sendStatus(204);
            })
            .catch(function (err) {
                next(err);
            });
    });

    // webHooks
    router.get('/projects/:ownerId/:projectName/hooks', ensureAuthenticated, function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {

                if (projectAccess && projectAccess.read) {
                    return metadataStorage.getProjectHooks(projectId);
                }

                res.status(403);
                throw new Error('Not authorized to read project [' + projectId + ']');
            })
            .then(function (hooks) {
                res.json(hooks);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such project') > -1) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.get('/projects/:ownerId/:projectName/hooks/:hookId', ensureAuthenticated, function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {

                if (projectAccess && projectAccess.read) {
                    return metadataStorage.getProjectHook(projectId, req.params.hookId);
                }

                res.status(403);
                throw new Error('Not authorized to read project [' + projectId + ']');
            })
            .then(function (hook) {
                res.json(hook);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such project') > -1 || err.message.indexOf('no such hook') > -1) {
                    res.status(404);
                }

                next(err);
            });
    });

    router.put('/projects/:ownerId/:projectName/hooks/:hookId', ensureAuthenticated, function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {
                if (projectAccess && projectAccess.write) {
                    return metadataStorage.addProjectHook(projectId, req.params.hookId, req.body);
                }

                res.status(403);
                throw new Error('Not authorized to modify project [' + projectId + ']');
            })
            .then(function (hook) {
                res.json(hook);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such project') > -1) {
                    res.status(404);
                } else if (err.message.indexOf('hook already exists') > -1) {
                    res.status(403);
                }
                next(err);
            });
    });

    router.patch('/projects/:ownerId/:projectName/hooks/:hookId', ensureAuthenticated, function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {

                if (projectAccess && projectAccess.write) {
                    return metadataStorage.updateProjectHook(projectId, req.params.hookId, req.body);
                }

                res.status(403);
                throw new Error('Not authorized to modify project [' + projectId + ']');
            })
            .then(function (hook) {
                res.json(hook);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such project') > -1 || err.message.indexOf('no such hook') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    router.delete('/projects/:ownerId/:projectName/hooks/:hookId', ensureAuthenticated, function (req, res, next) {
        var projectId = StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId, req.params.projectName),
            userId = getUserId(req),
            projectAuthParams = {
                entityType: authorizer.ENTITY_TYPES.PROJECT
            };

        authorizer.getAccessRights(userId, projectId, projectAuthParams)
            .then(function (projectAccess) {

                if (projectAccess && projectAccess.write) {
                    return metadataStorage.removeProjectHook(projectId, req.params.hookId);
                }

                res.status(403);
                throw new Error('Not authorized to modify project [' + projectId + ']');
            })
            .then(function (hooks) {
                res.json(hooks);
            })
            .catch(function (err) {
                if (err.message.indexOf('no such project') > -1 || err.message.indexOf('no such hook') > -1) {
                    res.status(404);
                }
                next(err);
            });
    });

    // squash
    router.put('/projects/:ownerId/:projectName/squash', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            data = {
                username: userId,
                projectId: StorageUtil.getProjectIdFromOwnerIdAndProjectName(req.params.ownerId,
                    req.params.projectName),
                fromCommit: req.body.fromCommit,
                toCommitOrBranch: req.body.toCommitOrBranch,
                message: req.body.message
            };

        safeStorage.squashCommits(data)
            .then(function () {
                res.sendStatus(201);
            })
            .catch(function (err) {
                next(err);
            });
    });

    logger.debug('creating list asset rules');

    router.get('/decorators', ensureAuthenticated, function (req, res) {
        var result = webgmeUtils.getComponentNames(gmeConfig.visualization.decoratorPaths);
        logger.debug('/decorators', {metadata: result});
        res.send(result);
    });

    // Plugins
    // TODO: These variables should not be defined here.
    // TODO: runningPlugins should be stored in a database.
    var runningPlugins = {};
    var PLUGIN_CONSTANTS = {
        RUNNING: 'RUNNING',
        FINISHED: 'FINISHED', // Could still be that result.success=false.
        ERROR: 'ERROR'
    };

    function getPlugin(name) {
        var pluginPath = 'plugin/' + name + '/' + name + '/' + name,
            Plugin,
            error,
            plugin;

        logger.debug('Configuration requested for plugin at', pluginPath);
        try {
            Plugin = requireJS(pluginPath);
        } catch (err) {
            error = err;
        }

        // This is weird, the second time requirejs simply returns with undefined.
        if (Plugin) {
            plugin = new Plugin();
            return plugin;
        } else {
            return error || new Error('Plugin is not available from: ' + pluginPath);
        }

    }

    router.get('/plugins', ensureAuthenticated, function (req, res) {
        var result = webgmeUtils.getComponentNames(gmeConfig.plugin.basePaths);
        logger.debug('/plugins', {metadata: result});
        res.send(result);
    });

    router.get('/plugins/metadata', ensureAuthenticated, function (req, res, next) {
        var pluginNames = webgmeUtils.getComponentNames(gmeConfig.plugin.basePaths),
            promises = [],
            basePath,
            i;

        for (i = 0; i < pluginNames.length; i += 1) {
            basePath = webgmeUtils.getBasePathByName(pluginNames[i], gmeConfig.plugin.basePaths);
            promises.push(Q.nfcall(fs.readFile, path.join(basePath, pluginNames[i], 'metadata.json'), 'utf8'));
        }

        Q.allSettled(promises)
            .then(function (fileRes) {
                var result = {};
                for (i = 0; i < fileRes.length; i += 1) {
                    if (fileRes[i].state === 'fulfilled') {
                        try {
                            result[pluginNames[i]] = JSON.parse(fileRes[i].value);
                        } catch (e) {
                            logger.error('Parsing metadata.json at "' +
                                path.join(basePath, pluginNames[i], 'metadata.json') + '", failed with error:\n' +
                                e.stack);
                        }
                    } else if (fileRes[i].state === 'rejected') {
                        if (fileRes[i].reason.code === 'ENOENT') {
                            logger.error('Plugin does not have a metadata.json', pluginNames[i]);
                        } else {
                            logger.error(fileRes[i].reason);
                        }
                    } else {
                        logger.error(new Error('Unknown q promise state'));
                    }
                }

                res.json(result);
            })
            .catch(next);
    });

    router.get(['/plugins/:pluginId/metadata', '/plugin/:pluginId/metadata'],
        ensureAuthenticated, function (req, res, next) {
            var basePath = webgmeUtils.getBasePathByName(req.params.pluginId, gmeConfig.plugin.basePaths);

            if (!basePath) {
                res.sendStatus(404);
                return;
            }

            Q.nfcall(fs.readFile, path.join(basePath, req.params.pluginId, 'metadata.json'), 'utf8')
                .then(function (content) {
                    res.json(JSON.parse(content));
                })
                .catch(function (err) {
                    if (err.code === 'ENOENT') {
                        res.sendStatus(404);
                    } else {
                        next(err);
                    }
                });
        });

    router.get(['/plugins/:pluginId/config', '/plugin/:pluginId/config'],
        ensureAuthenticated, function (req, res) {
            var plugin = getPlugin(req.params.pluginId);
            // TODO: In next release this should use metadata
            if (plugin instanceof Error) {
                logger.error(plugin);
                res.sendStatus(404);
            } else {
                res.send(plugin.getDefaultConfig());
            }
        });

    router.get(['/plugins/:pluginId/configStructure', '/plugin/:pluginId/configStructure'],
        ensureAuthenticated, function (req, res) {
            var plugin = getPlugin(req.params.pluginId);
            // TODO: In next release this should use metadata
            if (plugin instanceof Error) {
                logger.error(plugin);
                res.sendStatus(404);
            } else {
                res.send(plugin.getConfigStructure());
            }
        });

    function getPluginContext(req) {
        var userId = getUserId(req),
            pluginContext = {
                managerConfig: {
                    project: req.body.projectId,
                    branchName: req.body.branchName,
                    commit: req.body.commitHash,
                    activeNode: req.body.activeNode,
                    activeSelection: req.body.activeSelection,
                },
                pluginConfig: req.body.pluginConfig
            },
            workerParameters = {
                command: CONSTANTS.SERVER_WORKER_REQUESTS.EXECUTE_PLUGIN,
                name: req.params.pluginId,
                context: pluginContext
            };

        return getNewJWToken(userId)
            .then(function (token) {
                workerParameters.webgmeToken = token;

                return workerParameters;
            });
    }

    router.post(['/plugins/:pluginId/execute', '/plugin/:pluginId/execute'],
        function (req, res, next) {
            var resultId = GUID();

            getPluginContext(req)
                .then(function (context) {

                    middlewareOpts.workerManager.request(context, function (err, result) {
                        if (err) {
                            runningPlugins[resultId].status = PLUGIN_CONSTANTS.ERROR;
                            runningPlugins[resultId].err = err.message;
                        } else {
                            runningPlugins[resultId].status = PLUGIN_CONSTANTS.FINISHED;
                        }

                        runningPlugins[resultId].result = result;
                        runningPlugins[resultId].timeoutId = setTimeout(function () {
                            logger.warn('Plugin result timed out: ' + gmeConfig.plugin.serverResultTimeout + '[ms]',
                                resultId);
                            delete runningPlugins[resultId];
                        }, gmeConfig.plugin.serverResultTimeout);
                    });

                    runningPlugins[resultId] = {
                        status: PLUGIN_CONSTANTS.RUNNING,
                        //timeoutId: will be added after plugin finished
                        //result: null,
                        //error: null
                    };

                    res.send({resultId: resultId});
                })
                .catch(next);
        });

    router.post(['/plugins/:pluginId/run', '/plugin/:pluginId/run'],
        function (req, res, next) {
            getPluginContext(req)
                .then(function (context) {

                    middlewareOpts.workerManager.request(context, function (err, result) {
                        if (err && !result) {
                            next(err);
                        } else {
                            res.send(result);
                        }
                    });
                })
                .catch(next);
        });

    router.get(['/plugins/:pluginId/results/:resultId', '/plugin/:pluginId/results/:resultId'],
        ensureAuthenticated, function (req, res) {
            var pluginExecution = runningPlugins[req.params.resultId];
            logger.debug('Plugin-result request for ', req.params.pluginId, req.params.resultId);
            if (pluginExecution) {
                if (pluginExecution.status === PLUGIN_CONSTANTS.RUNNING) {
                    res.send(pluginExecution);
                } else {
                    // Remove the pluginExecution when it has finished or an error occurred.
                    clearTimeout(pluginExecution.timeoutId);
                    pluginExecution.timeoutId = undefined;
                    delete runningPlugins[req.params.resultId];
                    res.send(pluginExecution);
                }
            } else {
                res.sendStatus(404);
            }
        });

    // AddOns
    router.get(['/add-ons', '/addOns'], ensureAuthenticated, function (req, res) {
        var result = webgmeUtils.getComponentNames(gmeConfig.addOn.basePaths);
        logger.debug('/addOns', {metadata: result});
        res.send(result);
    });

    //router.get('/addOns/:addOnId/queryParams', ensureAuthenticated, function (req, res) {});
    //router.get('/addOns/:addOnId/queryParamsStructure', ensureAuthenticated, function (req, res) {});
    //router.post('/addOns/:addOnId/query', ensureAuthenticated, function (req, res) {});

    router.get('/seeds', ensureAuthenticated, function (req, res, next) {
        webgmeUtils.getSeedDictionary(gmeConfig)
            .then(function (seedDictionary) {
                logger.debug('/seeds', {metadata: seedDictionary});
                res.send(Object.keys(seedDictionary));
            })
            .catch(next);
    });

    router.get('/seeds/:seedName', ensureAuthenticated, function (req, res, next) {
        var seedName = req.params.seedName,
            userId = getUserId(req),
            webgmeToken;

        webgmeUtils.getSeedDictionary(gmeConfig)
            .then(function (seedDictionary) {
                if (seedDictionary.hasOwnProperty(seedName) === false) {
                    res.status(404);
                    throw new Error('Requested seed [' + seedName + '], does not exist among: '
                        + Object.keys(seedDictionary));
                } else if (seedToBlobHash.hasOwnProperty(seedName)) {
                    // It was already requested and exists on the blob-storage.
                    return seedToBlobHash[seedName];
                } else {
                    // Seed exists but hasn't been uploaded to blob-storage.
                    return getNewJWToken(userId)
                        .then(function (token) {
                            webgmeToken = token;

                            return Q.ninvoke(fs, 'readFile', seedDictionary[seedName]);
                        })
                        .then(function (content) {
                            var blobClient = new BlobClientClass({
                                serverPort: gmeConfig.server.port,
                                httpsecure: false,
                                server: '127.0.0.1',
                                webgmeToken: webgmeToken,
                                logger: logger.fork('BlobClient')
                            });

                            return blobClient.putFile(seedName + '.webgmex', content);
                        });
                }
            })
            .then(function (blobHash) {
                // TODO: Consider supporting metadata of seeds and parse and return it here..
                res.json({
                    blobHash: blobHash
                });
            })
            .catch(next);
    });

    // FIXME: This should be async
    function getVisualizersDescriptor() {
        //we merge the contents of the CONFIG.visualizerDescriptors by id
        var indexById = function (objectArray, id) {
                var i,
                    index = -1;
                for (i = 0; i < objectArray.length; i++) {
                    if (objectArray[i].id === id) {
                        index = i;
                        break;
                    }
                }

                return index;
            },
            getVisualizerDescriptor = function (path) {
                try {
                    var descriptor = fs.readFileSync(path, 'utf-8');
                    descriptor = JSON.parse(descriptor);
                    return descriptor;
                } catch (e) {
                    //we do not care much of the error just give back an empty array
                    logger.error(e);
                    return [];
                }
            },
            allVisualizersDescriptor = [],
            i, j;

        for (i = 0; i < gmeConfig.visualization.visualizerDescriptors.length; i++) {
            var descriptor = getVisualizerDescriptor(gmeConfig.visualization.visualizerDescriptors[i]);
            if (descriptor.length) {
                for (j = 0; j < descriptor.length; j++) {
                    var index = indexById(allVisualizersDescriptor, descriptor[j].id);
                    if (index !== -1) {
                        allVisualizersDescriptor[index] = descriptor[j];
                    } else {
                        allVisualizersDescriptor.push(descriptor[j]);
                    }
                }
            }
        }
        return allVisualizersDescriptor.sort(function (a, b) {
            if (a.id < b.id) {
                return -1;
            }
            if (a.id > b.id) {
                return 1;
            }
            return 0;
        });
    }

    // FIXME: this should be JSON
    router.get('/visualizers', ensureAuthenticated, function (req, res) {
        var result = getVisualizersDescriptor();
        logger.debug('/visualizers', {metadata: result});
        res.send(result);
    });

    router.get('/status', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req),
            result = {
                addresses: middlewareOpts.server.getAddresses(),
                addOns: null,
                serverWorkers: null,
                sockets: middlewareOpts.server.getSocketsInfo(),
                webSockets: null,
            };

        gmeAuth.getUser(userId)
            .then(function (userData) {
                if (gmeConfig.authentication.enable && !userData.siteAdmin) {
                    res.status(403);
                    throw new Error('site admin role is required for this operation');
                }

                result.webSockets = middlewareOpts.webSocket.getStatus();

                if (gmeConfig.addOn.enable) {
                    return middlewareOpts.addOnEventPropagator.getStatus({});
                } else {
                    return null;
                }
            })
            .then(function (addOnStatus) {
                result.addOns = addOnStatus;

                return Q.ninvoke(middlewareOpts.workerManager, 'getStatus');
            })
            .then(function (serverWorkersStatus) {
                result.serverWorkers = serverWorkersStatus;

                res.json(result);
            })
            .catch(next);
    });

    router.get(['/status/add-ons', '/addOnStatus'], ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        if (gmeConfig.addOn.enable) {
            gmeAuth.getUser(userId)
                .then(function (userData) {
                    if (gmeConfig.authentication.enable && !userData.siteAdmin) {
                        res.status(403);
                        throw new Error('site admin role is required for this operation');
                    }

                    return middlewareOpts.addOnEventPropagator.getStatus({});
                })
                .then(function (status) {
                    res.json(status);
                })
                .catch(next);
        } else {
            res.sendStatus(404);
        }
    });

    router.get('/status/server-workers', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {
                if (gmeConfig.authentication.enable && !userData.siteAdmin) {
                    res.status(403);
                    throw new Error('site admin role is required for this operation');
                }

                return Q.ninvoke(middlewareOpts.workerManager, 'getStatus');
            })
            .then(function (status) {
                res.json(status);
            })
            .catch(next);
    });

    router.get('/status/web-sockets', ensureAuthenticated, function (req, res, next) {
        var userId = getUserId(req);

        gmeAuth.getUser(userId)
            .then(function (userData) {
                if (gmeConfig.authentication.enable && !userData.siteAdmin) {
                    res.status(403);
                    throw new Error('site admin role is required for this operation');
                }

                res.json(middlewareOpts.webSocket.getStatus());
            })
            .catch(next);
    });

    router.use('*', function (req, res, next) {
        res.status(404);
        next(new Error());
    });

    // error handling (NOTE: it is important to have this function signature with 4 arguments!)
    // eslint-disable-next-line
    router.use(function (err, req, res, next) {
        var errorMessage = {
                401: 'Authentication required',
                403: 'Forbidden',
                404: 'Not found'
            },
            message = err.message ? err.message : err;

        if (res.statusCode === 200) {
            if (err.message.indexOf('Not authorized') > -1) {
                err.status = err.status || 403;
            }
            res.status(err.status || 500);
        }

        if (errorMessage.hasOwnProperty(res.statusCode)) {
            message = errorMessage[res.statusCode];
        }

        if (res.statusCode === 500) {
            logger.error(err);
        }

        res.json({
            message: message,
            documentation_url: '',
            error: err.message ? err.message : err // FIXME: only in dev mode
        });
    });

    // attach the api to the requested path
    logger.debug('Supported api path: ' + versionedAPIPath);
    app.use(versionedAPIPath, router);

    logger.debug('Latest api path: ' + latestAPIPath);
    app.use(latestAPIPath, router);

    return Q();
}
184011
public boolean containsProgramPath(String path) {
        return registryMap.containsKey(path) && registryMap.get(path).getProgram() != null;
    }
484023
function NotFoundError(name) {
  Error.call(this);
  Error.captureStackTrace(this, arguments.callee);
  this.name = 'Middleware Not Found Error';
  this.message = name + ' not found in the current stack';
}
76209
static boolean objectHasDirectoryPath(String objectName) {
    return !Strings.isNullOrEmpty(objectName)
        && objectName.endsWith(GoogleCloudStorage.PATH_DELIMITER);
  }
255372
public static boolean checkParam(Map<String, String> params, String key) {
        boolean result = false;
        if (params.containsKey("sign")) {
            String sign = params.get("sign");
            params.remove("sign");
            StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
            SignUtils.buildPayParams(buf, params, false);
            String preStr = buf.toString();
            String signReceive = MD5Utils.sign(preStr, "&key=" + key, "utf-8");
            result = sign.equalsIgnoreCase(signReceive);
        }
        return result;
    }