@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, @RealStartPosition INTEGER = 0, @RealEndPosition INTEGER = 0 ;
				 DECLARE @RC INTEGER = 0, @chk INTEGER = 0 ;
				 DECLARE @Project_UUID VARCHAR(255) ;
				 DECLARE @VarName VARCHAR(250) ;
				 DECLARE @ResourceTypeID_Prog INTEGER = (SELECT TOP 1 ResourceID FROM ResourceTypes WHERE Name = 'PROGRAM') ;


				 --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;


                      SET @chk = COALESCE((SELECT COUNT(DISTINCT VarName) FROM #BRDVariableNameInput), 0) + 1;  


				 --3. DETERMINE VariableID based on filters
				 IF OBJECT_ID('tempdb..#varf8') IS NOT NULL DROP TABLE #varf8 ;
				 CREATE TABLE #varf8(VarID INTEGER, VarFlag INT) ; 
	
				 -- get VarID for main variable
				 INSERT INTO #varf8(VarID, VarFlag)
				 SELECT v.VarID, 1 AS VarFlag
		         FROM BRD_Variables v 
		         WHERE v.VarName  = @VarName
		                 AND EXISTS (SELECT 1 FROM #BRDVariableHashInput hi WHERE v.VariableHash = hi.VarHash) ;

			            


				 -- get VarID's for the affinity variables
				 INSERT INTO #varf8(VarID, VarFlag)
				 SELECT v.VarID, 1 + f.VarFlag
				 FROM BRD_Variables v
					 INNER JOIN ( SELECT s.VarName, ROW_NUMBER() OVER(ORDER BY s.VarName) AS VarFlag 
							    FROM (SELECT DISTINCT VarName FROM #BRDVariableNameInput) s  
							    ) f ON v.VarName = f.VarName ;
		              
	                --SELECT * FROM #varf8


				--4.GET variable's statements for all variables
				IF OBJECT_ID('tempdb..#stmt81') IS NOT NULL DROP TABLE #stmt81;
				CREATE TABLE #stmt81 (
							 VarID INTEGER,
							 OriginalVarID INTEGER,
							 StatementTypeID INTEGER,
							 ProgID INTEGER, 
							 OccurID INTEGER,
							 PathID INTEGER,
							 StartRow INTEGER,
							 EndRow INTEGER,
							 StartCol INTEGER,
							 EndCol INTEGER,
							 IsCalculation TINYINT,
							 IsCondition   TINYINT,
							 IsAssignment  TINYINT,
							 VarFlag INTEGER ) ;



                IF( @chk > 1 AND @chk = (SELECT MAX(VarFlag) FROM #varf8)) -- go further only if there are, at least, main_variable + one more variable 
				BEGIN

				        INSERT INTO #stmt81
					        (VarID, OriginalVarID, StatementTypeID, ProgID, OccurID, PathID
                            ,StartRow, EndRow, StartCol, EndCol 
                            ,IsCalculation, IsCondition, IsAssignment
                            ,VarFlag)
					   SELECT VarID, OriginalVarID, StatementTypeID, ProgID, OccurID, PathID
                              ,StartRow, EndRow, StartCol, EndCol 
                              ,IsCalculation, IsCondition, IsAssignment
                              ,VarFlag
						FROM (	  
								SELECT   ds1.VarID ,ds1.VarID AS OriginalVarID
								        ,ds1.StatementTypeID, ds1.ProgID, ds1.OccurID, ds1.PathID
										,ds1.StartRow ,ds1.EndRow ,ds1.StartCol ,ds1.EndCol
										,ds1.IsCalculation ,ds1.IsCondition ,ds1.IsAssignment
										,f1.VarFlag
								FROM BRD_DirectStatements ds1
										INNER JOIN #varf8 f1 ON ds1.VarID = f1.VarID 
								WHERE ds1.IsCalculation + ds1.IsCondition + ds1.IsAssignment > 0
					   
					            UNION
								-- indirect statements
								SELECT   vh2.ChildVarID AS VarID ,ds2.VarID AS OriginalVarID 
                                        ,ds2.StatementTypeID, ds2.ProgID, ds2.OccurID, ds2.PathID
										,ds2.StartRow ,ds2.EndRow ,ds2.StartCol ,ds2.EndCol
										,ds2.IsCalculation ,ds2.IsCondition ,ds2.IsAssignment
										,f2.VarFlag
								FROM BRD_DirectStatements ds2 
									INNER JOIN BRD_VariableHierarchy vh2 ON ds2.VarID = vh2.VarID AND vh2.ChildLevel = 10088
                                    INNER JOIN #varf8 f2 ON vh2.ChildVarID = f2.VarID 
								WHERE ds2.Is88VarLvlCondition = 1 
						      ) x ;
				END;






	

			    --5.GET variable's mutual statements
		        IF OBJECT_ID('tempdb..#stmt82') IS NOT NULL DROP TABLE #stmt82;
				SELECT  rd.ResourceName AS ProgramName, src1.ProgID, src1.PathID, src1.StatementTypeID 
					   ,src1.StartRow, src1.EndRow,  src1.StartCol, src1.EndCol
					   ,src1.OccurID, src1.VarID 
					   ,COALESCE(bc.CategoryShortAlias, '') AS StatementMark 
					   ,ROW_NUMBER() OVER(ORDER BY rd.ResourceName, src1.ProgID, src1.PathID, src1.StatementTypeID, src1.StartRow, src1.EndRow, src1.StartCol, src1.EndCol, src1.StatementMark, src1.OccurID, src1.VarID) AS RN           
				INTO #stmt82
				FROM (	
                        SELECT DISTINCT s.ProgID, s.PathID, s.StatementTypeID, s.OccurID, s.StartRow , s.EndRow, s.StartCol, s.EndCol, s.VarID,   
							   CASE WHEN s.IsCalculation = 1   THEN 1
								    WHEN s.IsCondition   = 1   THEN 2
								    WHEN s.IsAssignment  = 1   THEN 7
								    ELSE NULL
							    END AS StatementMark
					    FROM #stmt81 s
					    WHERE s.OccurID IN  ( 
												SELECT x.OccurID 
												FROM #stmt81 x
												WHERE  NOT EXISTS (
																	SELECT 1 
																	FROM ( 
																			-- parent (VarFlag=1)-> child (VarFlag>1)		
																				SELECT s1.OccurID 
																				FROM #stmt81 s1
																				WHERE s1.IsCondition = 1
																					AND EXISTS (SELECT 1 FROM #varf8 f1 WHERE f1.VarFlag = 1 AND f1.VarID = s1.VarID)
																					AND EXISTS (SELECT 1 FROM #varf8 f2 WHERE f2.VarFlag > 1 AND f2.VarID = s1.OriginalVarID) 
																				UNION
																				-- child (VarFlag=1)-> parent (VarFlag>1)	
																				SELECT s2.OccurID 
																				FROM #stmt81 s2
																				WHERE s2.IsCondition = 1
																					AND EXISTS (SELECT 1 FROM #varf8 f1 WHERE f1.VarFlag > 1 AND f1.VarID = s2.VarID)
																					AND EXISTS (SELECT 1 FROM #varf8 f2 WHERE f2.VarFlag = 1 AND f2.VarID = s2.OriginalVarID)    
																			) f WHERE f.OccurID = x.OccurID
																	)
												GROUP BY x.OccurID 
												HAVING COUNT(DISTINCT x.VarFlag) = (SELECT MAX(VarFlag) FROM #varf8) -- all variables together into same statement
						                    )
				    )src1
					   INNER JOIN BRD_ResourceDetails rd ON rd.ResourceID = src1.ProgID  AND rd.ResourceTypeID = @ResourceTypeID_Prog
					   LEFT OUTER JOIN BRD_Category bc ON src1.StatementMark = bc.CategoryID AND bc.IsActive = 1 ;

		           SET @RC = @@ROWCOUNT;  	  

		           --SELECT * FROM #stmt82




		       
			    --6.DETERMINE GlobalRN
		    		IF OBJECT_ID('tempdb..#stmt83') IS NOT NULL DROP TABLE #stmt83;
				SELECT  src1.ProgramName, src1.ProgID, src1.PathID, src1.StatementTypeID 
					   ,src1.StartRow, src1.EndRow,  src1.StartCol, src1.EndCol
					   ,src1.OccurID, src1.VarID 
					   ,src1.StatementMark 
					   ,src1.RN
					   ,DENSE_RANK() OVER(ORDER BY src2.MIN_RN) AS GlobalRN -- for paging purpose (provide compact blocks/statements)
                 INTO #stmt83
				 FROM #stmt82 src1
				     INNER JOIN ( SELECT OccurID, MIN(RN) AS MIN_RN
					              FROM #stmt82
							      GROUP BY OccurID
					            ) src2 ON src1.OccurID = src2.OccurID  ;  


                -- 7.OUTPUT
			 SET  @RealStartPosition =  COALESCE( (SELECT GlobalRN FROM #stmt83 WHERE RN = @StartPosition), @StartPosition);
			 SET  @RealEndPosition   =  COALESCE( (SELECT GlobalRN FROM #stmt83 WHERE RN = (@StartPosition + @NumberOfRows - 1)), (@StartPosition + @NumberOfRows - 1));

			
			
			 SELECT
				    /*@Project_UUID  AS Project_UUID,*/
				     src.ProgramName
				    ,src.ProgID AS ProgramID
				    ,pth.PathStr
				    ,src.OccurID
				    ,st.Description
				    ,src.StartRow, src.EndRow, src.StartCol, src.EndCol
				    ,v.VariableHash AS Variable_UUID , v.VarName
				    ,src.StatementMark 
				    ,src.GlobalRN ,src.RN ,@RC AS NR
			 FROM (
				    SELECT  ProgramName, ProgID, PathID, StatementTypeID 
					      ,StartRow ,EndRow ,StartCol ,EndCol
					      ,OccurID ,VarID ,StatementMark 
					      ,RN ,GlobalRN
		              FROM #stmt83
				    WHERE GlobalRN BETWEEN  @RealStartPosition  AND  @RealEndPosition 		 
				  )src
					   INNER JOIN BRD_Variables v ON v.VarID = src.VarID
					   INNER JOIN Statements st   ON st.StatementType = src.StatementTypeID
					   INNER JOIN BRD_Paths pth       ON pth.PathID = src.PathID
 			 ORDER BY src.RN
			 OPTION(FAST 500);


               --9.CLEANUP
			 IF OBJECT_ID('tempdb..#varf8') IS NOT NULL  DROP TABLE #varf8;
			 IF OBJECT_ID('tempdb..#stmt81') IS NOT NULL DROP TABLE #stmt81;
			 IF OBJECT_ID('tempdb..#stmt82') IS NOT NULL DROP TABLE #stmt82;
			 IF OBJECT_ID('tempdb..#stmt83') IS NOT NULL DROP TABLE #stmt83;

END;
