@Project_UUID_IN  VARCHAR(255),
@VarName_IN       VARCHAR(250), 
@StartPosition_IN INTEGER, 
@NumberOfRows_IN  INTEGER	
AS 
BEGIN
SET XACT_ABORT ON
SET NOCOUNT ON

		  --1. DECLARATION AREA
			 DECLARE @StartPosition INTEGER, @NumberOfRows INTEGER;
			 DECLARE @RC INTEGER = 0;
			 DECLARE @Project_UUID VARCHAR(255);
			 DECLARE @VarName VARCHAR(250);



		   --2. SET FINAL VALUES FOR WORK VARIABLES
		   SET @StartPosition = COALESCE(NULLIF(@StartPosition_IN, -1), 1) ;
		   SET @NumberOfRows  = COALESCE(NULLIF(@NumberOfRows_IN, -1), 2147480000) ; 
		   SET @VarName = COALESCE(LTRIM(RTRIM(@VarName_IN)), '');
		   SET @Project_UUID_IN = COALESCE(LTRIM(RTRIM(@Project_UUID_IN)), '!');



		   SELECT @Project_UUID = ProjectGUID
		   FROM  BRD_Status  
		   WHERE BRDID = (SELECT MAX(BRDID) FROM BRD_Status WHERE BRDProcessStatusTypeID = 2); -- last BRD succssfull
													 		
		   SET @Project_UUID = COALESCE(LTRIM(RTRIM(@Project_UUID)), '?');


		   IF (@Project_UUID != @Project_UUID_IN) 
			    BEGIN 
						  RAISERROR ('BRD - wrong project.', -- Message text.  
								    16, -- Severity.  
								    1 -- State.  
								    ); 
						  RETURN;

				END;



	    --3. DETERMINE Variable based on filters
	     -- table is usefull when we deal with VarName since there are many VarID's under a name
		   IF OBJECT_ID('tempdb..#varf7') IS NOT NULL DROP TABLE #varf7;
		   CREATE TABLE #varf7  (VarID INTEGER NOT NULL PRIMARY KEY) 
	
		   INSERT INTO #varf7(VarID)
           SELECT v.VarID
		   FROM BRD_Variables v 
		   WHERE v.VarName = @VarName
		         AND EXISTS (SELECT 1 FROM #BRDVariableHashInput hi WHERE v.VariableHash = hi.VarHash) ;



        --3'.PICK-UP variable hierarchy for 88 lvl variable  
            IF OBJECT_ID('tempdb..#vh7') IS NOT NULL DROP TABLE #vh7;
			CREATE TABLE #vh7 (VarID INTEGER NOT NULL, ChildVarID INTEGER NOT NULL);

			INSERT INTO #vh7 (VarID, ChildVarID)
			SELECT x.VarID ,x.ChildVarID
			FROM (
					SELECT h1.VarID ,h1.ChildVarID
					FROM BRD_VariableHierarchy h1
					WHERE EXISTS (SELECT 1 FROM #varf7 f WHERE h1.VarID = f.VarID) 
						AND h1.ChildLevel = 10088
					
					UNION

					SELECT h2.VarID ,h2.ChildVarID
					FROM BRD_VariableHierarchy h2
					WHERE  EXISTS (SELECT 1 FROM #varf7 f WHERE h2.ChildVarID = f.VarID)
						AND h2.ChildLevel = 10088
			     )x;
                --SELECT * FROM #vh7

		  --4.GET Statements for main variables
		   IF OBJECT_ID('tempdb..#stmt71') IS NOT NULL DROP TABLE #stmt71;
           SELECT VarID ,OccurID ,IsCalculation ,IsCondition ,IsAssignment
		   INTO #stmt71
           FROM (  
					SELECT ds.VarID ,ds.OccurID ,ds.IsCalculation ,ds.IsCondition ,ds.IsAssignment
					FROM BRD_DirectStatements ds
					WHERE EXISTS (SELECT 1 FROM #varf7 f WHERE ds.VarID = f.VarID) 
							AND ds.IsCalculation + ds.IsCondition + ds.IsAssignment > 0 
		  
		            UNION
                    -- indirect statements
					SELECT vh.ChildVarID AS VarID ,ds.OccurID ,ds.IsCalculation ,ds.IsCondition ,ds.IsAssignment 
					FROM BRD_DirectStatements ds 
						INNER JOIN BRD_VariableHierarchy vh ON ds.VarID = vh.VarID AND vh.ChildLevel = 10088
					WHERE EXISTS (SELECT 1 FROM #varf7 f WHERE vh.ChildVarID = f.VarID)  
						  AND ds.Is88VarLvlCondition = 1 
	        	) x ;
		  --SELECT * FROM #stmt71 WHERE statementcategory = 'I'


		  --5.0 GET Statements for related variables and check affinity
		   IF OBJECT_ID('tempdb..#stmt72') IS NOT NULL DROP TABLE #stmt72;
		   SELECT v.VarID, v.VarName, v.VariableHash, src.TogetherInCalculation, src.TogetherInCondition, src.TogetherInAssignment, src.ProgID
           INTO #stmt72
		   FROM 
				( 
			   SELECT  DISTINCT
						 ds.OccurID           
						,ds.VarID
					   --,st.VarID AS BaseVarID
					   ,CASE WHEN ds.IsCalculation = 1 AND st.IsCalculation = 1 THEN 1
							 ELSE 0
					   END AS TogetherInCalculation
					   ,CASE WHEN ds.IsCondition = 1 AND st.IsCondition = 1 THEN 1
							 ELSE 0
					   END AS TogetherInCondition
					   ,CASE WHEN ds.IsAssignment = 1 AND st.IsAssignment = 1 THEN 1
							 ELSE 0
					   END AS TogetherInAssignment
					   ,ds.ProgID
				FROM   (
						SELECT   ds1.OccurID           
								,ds1.VarID
								,ds1.IsCalculation 
								,ds1.IsCondition  ,ds1.IsAssignment  ,ds1.ProgID
						FROM BRD_DirectStatements ds1
						WHERE  NOT EXISTS (SELECT 1 FROM #varf7 f WHERE ds1.VarID = f.VarID) 
								AND  ds1.IsCalculation + ds1.IsCondition + ds1.IsAssignment > 0
                       
						UNION ALL
                        -- indirect statements
						SELECT   ds2.OccurID           
								,vh.ChildVarID AS VarID
								,ds2.IsCalculation 
								,ds2.IsCondition  ,ds2.IsAssignment  ,ds2.ProgID
						FROM BRD_DirectStatements ds2 
								INNER JOIN BRD_VariableHierarchy vh ON ds2.VarID = vh.VarID AND vh.ChildLevel = 10088 
						WHERE NOT EXISTS (SELECT 1 FROM #varf7 f WHERE vh.ChildVarID = f.VarID)  
						      AND ds2.Is88VarLvlCondition = 1      	 
				       ) ds 
				          INNER JOIN #stmt71 st  ON st.OccurID = ds.OccurID      AND st.VarID != ds.VarID
				          LEFT OUTER JOIN #vh7 h1 ON ds.IsCondition = 1 AND st.VarID   = h1.VarID        AND ds.VarID = h1.ChildVarID
				          LEFT OUTER JOIN #vh7 h2 ON st.IsCondition = 1 AND st.VarID   = h2.ChildVarID   AND ds.VarID = h2.VarID
				WHERE h1.VarID IS NULL AND h2.VarID IS NULL  
				) src
				     INNER JOIN BRD_Variables v ON v.VarID = src.VarID
			    WHERE src.TogetherInCalculation +  src.TogetherInCondition +  src.TogetherInAssignment > 0 ;



				--5.1 GET Statements for related variables and check affinity
				IF OBJECT_ID('tempdb..#stmt73') IS NOT NULL DROP TABLE #stmt73;
				SELECT       src.VarName   
						  ,SUM(src.TogetherInCalculation) AS NrTogetherInCalculation  
						  ,SUM(src.TogetherInCondition) AS NrTogetherInCondition 
						  ,SUM(src.TogetherInAssignment) AS NrTogetherInAssignment
						  ,SUM(src.TogetherInCalculation + src.TogetherInCondition + src.TogetherInAssignment) AS Total
						  ,COUNT(DISTINCT src.ProgID) AS NrPrograms
						  ,ROW_NUMBER() OVER(ORDER BY SUM(src.TogetherInCalculation + src.TogetherInCondition + src.TogetherInAssignment) DESC, src.VarName) AS RN     
				INTO #stmt73
				FROM  #stmt72 src
				GROUP BY src.VarName;
			               
				SET @RC = @@ROWCOUNT; 



			   -- 6.OUTPUT
			     -- 6.1 GET VarName and VarHash for variables directed on output  
				    TRUNCATE TABLE #BRDVariableHashOutput;
                    INSERT INTO #BRDVariableHashOutput(VarName, VarHash)
			        SELECT DISTINCT st2.VarName, st2.VariableHash
				    FROM  #stmt72 st2
					     INNER JOIN #stmt73 st3 ON st2.VarName = st3.VarName AND st3.RN BETWEEN @StartPosition  AND (@StartPosition + @NumberOfRows - 1)  
                       ; 
                              		    


                   -- 6.2 OUTPUT General
				SELECT  /*@Project_UUID AS Project_UUID,*/
					   VarName, NrTogetherInCalculation, NrTogetherInCondition, NrTogetherInAssignment, NrPrograms, /*Total,*/ RN
					   ,@RC AS NR
				FROM  #stmt73
				WHERE RN BETWEEN  @StartPosition  AND (@StartPosition + @NumberOfRows - 1)  
 				ORDER BY RN
				OPTION(FAST 500);
					  


                    --7.CLEANUP
				IF OBJECT_ID('tempdb..#vh7')   IS NOT NULL  DROP TABLE #vh7;
				IF OBJECT_ID('tempdb..#varf7') IS NOT NULL  DROP TABLE #varf7;
                IF OBJECT_ID('tempdb..#stmt71') IS NOT NULL DROP TABLE #stmt71;
				IF OBJECT_ID('tempdb..#stmt72') IS NOT NULL DROP TABLE #stmt72;
				IF OBJECT_ID('tempdb..#stmt73') IS NOT NULL DROP TABLE #stmt73;

END;
