class RestfulGraphDatabase {

    @POST
    @Path( PATH_NAMED_NODE_INDEX )
    @Consumes( MediaType.APPLICATION_JSON )
    public Response addToNodeIndex( @PathParam( "indexName" ) String indexName, @QueryParam( "unique" ) String unique,
                                    @QueryParam( "uniqueness" ) String uniqueness, String postBody )
    {
        int otherHeaders = 512;
        int maximumSizeInBytes = config.getInt( ServerSettings.maximum_response_header_size.name() ) - otherHeaders;

        try
        {
            Map<String, Object> entityBody;
            Pair<IndexedEntityRepresentation, Boolean> result;

            switch ( unique( unique, uniqueness ) )
            {
                case GetOrCreate:
                    entityBody = input.readMap( postBody, "key", "value" );

                    String getOrCreateValue = String.valueOf( entityBody.get( "value" ) );
                    if ( getOrCreateValue.length() > maximumSizeInBytes )
                    {
                        return valueTooBig();
                    }

                    result = actions.getOrCreateIndexedNode( indexName,
                            String.valueOf( entityBody.get( "key" ) ),
                            getOrCreateValue, extractNodeIdOrNull( getStringOrNull(
                            entityBody, "uri" ) ), getMapOrNull( entityBody, "properties" ) );
                    return result.other() ? output.created( result.first() )
                                          : output.okIncludeLocation( result.first() );

                case CreateOrFail:
                    entityBody = input.readMap( postBody, "key", "value" );

                    String createOrFailValue = String.valueOf( entityBody.get( "value" ) );
                    if ( createOrFailValue.length() > maximumSizeInBytes )
                    {
                        return valueTooBig();
                    }

                    result = actions.getOrCreateIndexedNode( indexName,
                            String.valueOf( entityBody.get( "key" ) ),
                            createOrFailValue, extractNodeIdOrNull( getStringOrNull(
                            entityBody, "uri" ) ), getMapOrNull( entityBody, "properties" ) );
                    if ( result.other() )
                    {
                        return output.created( result.first() );
                    }

                    String uri = getStringOrNull( entityBody, "uri" );

                    if ( uri == null )
                    {
                        return output.conflict( result.first() );
                    }

                    long idOfNodeToBeIndexed = extractNodeId( uri );
                    long idOfNodeAlreadyInIndex = extractNodeId( result.first().getIdentity() );

                    if ( idOfNodeToBeIndexed == idOfNodeAlreadyInIndex )
                    {
                        return output.created( result.first() );
                    }

                    return output.conflict( result.first() );

                default:
                    entityBody = input.readMap( postBody, "key", "value", "uri" );
                    String value = String.valueOf( entityBody.get( "value" ) );

                    if ( value.length() > maximumSizeInBytes )
                    {
                        return valueTooBig();
                    }

                    return output.created( actions.addToNodeIndex( indexName,
                            String.valueOf( entityBody.get( "key" ) ),
                            value, extractNodeId( entityBody.get( "uri" )
                            .toString() ) ) );

            }
        }
        catch ( UnsupportedOperationException e )
        {
            return output.methodNotAllowed( e );
        }
        catch ( IllegalArgumentException | BadInputException e )
        {
            return output.badRequest( e );
        }
        catch ( Exception e )
        {
            return output.serverError( e );
        }
    }

    public  RestfulGraphDatabase( @Context InputFormat input,
                                 @Context OutputFormat output,
                                 @Context DatabaseActions actions,
                                 @Context Configuration config );

}