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

			  -- DECLARATION AREA
			  DECLARE @StartPosition INTEGER, @NumberOfRows INTEGER ;
			  DECLARE @RC INTEGER = 0, @IsStatementTypeFilter TINYINT = 0 ;
			  DECLARE @Project_UUID VARCHAR(255) ;
			  DECLARE @VarName VARCHAR(250) ;
			  DECLARE @ResourceTypeID_Prog INTEGER = (SELECT TOP 1 ResourceID FROM ResourceTypes WHERE Name = 'PROGRAM') ;

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


	   -- DETERMINE Variable based on filters
		   IF OBJECT_ID('tempdb..#varf61') IS NOT NULL DROP TABLE #varf61 ;
		   CREATE TABLE #varf61 (VarID INTEGER NOT NULL PRIMARY KEY) ;

		   INSERT INTO #varf61 (VarID)
           SELECT v.VarID
		   FROM BRD_Variables v 
		   WHERE v.VarName  = @VarName
		         AND 
			     EXISTS (SELECT 1 FROM #BRDVariableHashInput hi WHERE v.VariableHash = hi.VarHash) ;
	  


	       -- CHECK if we have to filter by StatementTypeID	  
			IF EXISTS (SELECT 1 FROM #BRDStatementTypeInput)
			BEGIN
                 SET @IsStatementTypeFilter = 1 ;
            END ;



	       -- DETERMINE Statements where variables are involved 
	        IF OBJECT_ID('tempdb..#varstmt61') IS NOT NULL DROP TABLE #varstmt61 ;
			CREATE TABLE #varstmt61( VarIDConsolidate  INTEGER 
			                        ,VarID             INTEGER
								    ,StatementTypeID   INTEGER
								    ,ProgID            INTEGER
									,CopyID            INTEGER
									,CopyTypeID        INTEGER
								   ) ; 


			INSERT INTO #varstmt61
			          (VarIDConsolidate ,VarID ,StatementTypeID ,ProgID, CopyID, CopyTypeID) 
	        SELECT   v.VarIDConsolidate ,v.VarID ,src1.StatementTypeID ,src1.ProgID , src1.CopyID, src1.CopyTypeID
			FROM (
			       
									   SELECT ds.VarID 
											 ,ds.StatementTypeID
											 ,ds.ProgID
											 ,ds.CopyID
											 ,ds.CopyTypeID
									   FROM BRD_DirectStatements ds 
									   WHERE EXISTS (SELECT 1 FROM #varf61 v WHERE ds.VarID = v.VarID)
									         AND ( 
										          @IsStatementTypeFilter = 0
										          OR
												  EXISTS (SELECT 1 FROM #BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
										         )
												 
									   UNION 

									   SELECT vh.ChildVarID AS VarID 
											 ,ds.StatementTypeID
											 ,ds.ProgID
											 ,ds.CopyID
											 ,ds.CopyTypeID
									   FROM BRD_DirectStatements ds 
										    INNER JOIN BRD_VariableHierarchy vh ON ds.VarID = vh.VarID 
									   WHERE EXISTS (SELECT 1 FROM #varf61 v WHERE vh.ChildVarID = v.VarID)
										    AND (ds.IsFileIO + ds.IsMQ + ds.IsScreen + ds.Is88VarLvlCondition > 0) 
											AND ( 
										           @IsStatementTypeFilter = 0
										           OR
												   EXISTS (SELECT 1 FROM #BRDStatementTypeInput f WHERE ds.StatementTypeID = f.StatementTypeID)
										         ) 
				  )src1 
					   INNER JOIN BRD_Variables v ON src1.VarID = v.VarID ; 


           -- If filtered by STATEMENT TYPE then keep only variables involved in such statements 
			IF @IsStatementTypeFilter = 1
			BEGIN
                 DELETE d 
				 FROM #varf61 d 
				 WHERE NOT EXISTS (SELECT 1 
				                   FROM #varstmt61 v
								   WHERE d.VarID = v.VarID) ;
             END ;



			--Determine Total Number Of Elements
	        IF OBJECT_ID('tempdb..#varrn61') IS NOT NULL DROP TABLE #varrn61 ;
			SELECT VarIDConsolidate
			      ,DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID, DefinitionObjectPathID 
				  ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol 
				  ,CountDistProgUsingVar  ,CountDistCopyUsingVar
				  ,DENSE_RANK() OVER(ORDER BY DefinedInCopy DESC, CountDistProgUsingVar DESC,CountDistCopyUsingVar DESC, VarIDConsolidate) AS RN 
			INTO #varrn61
			FROM (
						    SELECT   src.VarIDConsolidate ,DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID
						        ,DefinitionObjectPathID ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol
								,COALESCE(usg.CountDistProgUsingVar, 0)  AS CountDistProgUsingVar
								,COALESCE(usg.CountDistCopyUsingVar, 0)  AS CountDistCopyUsingVar
						    FROM (
									SELECT    v1.VarIDConsolidate
											, CASE WHEN v1.CopyID IS NOT NULL THEN 1               ELSE 0                    END AS DefinedInCopy
											, CASE WHEN v1.CopyID IS NOT NULL THEN v1.CopyID       ELSE v1.ProgID            END AS DefinitionObjectID
											, CASE WHEN v1.CopyID IS NOT NULL THEN v1.CopyTypeID   ELSE @ResourceTypeID_Prog END AS DefinitionObjectTypeID
											, v1.PathID     AS DefinitionObjectPathID
											, v1.StartRow   AS VarPositionStartRow 
											, v1.EndRow     AS VarPositionEndRow 
											, v1.StartCol   AS VarPositionStartCol 
											, v1.EndCol     AS VarPositionEndCol
											, ROW_NUMBER() OVER(PARTITION BY VarIDConsolidate ORDER BY v1.CopyID, v1.CopyTypeID, v1.ProgID) AS RNflt -- in case there are multiplication due to Program (DefinitionObjectID)
								   FROM BRD_Variables v1
								   WHERE EXISTS (SELECT 1 FROM #varf61 f WHERE f.VarID = v1.VarID)
							 ) src 
								  LEFT OUTER JOIN 
												(
														SELECT VarIDConsolidate, SUM(CountDistProgUsingVar) AS CountDistProgUsingVar, SUM(CountDistCopyUsingVar) AS CountDistCopyUsingVar
														FROM ( 

																	SELECT VarIDConsolidate
																		,COUNT(DISTINCT ProgID) AS CountDistProgUsingVar
																		,0 AS CountDistCopyUsingVar
																	FROM #varstmt61
																	WHERE CopyID IS NULL
																	GROUP BY VarIDConsolidate

																	UNION ALL

																	SELECT x.VarIDConsolidate
																		,0 AS CountDistProgUsingVar
																		,COUNT(x.CopyID) AS CountDistCopyUsingVar
																	FROM (  
																			SELECT VarIDConsolidate, CopyID, CopyTypeID 
																			FROM #varstmt61 
																			WHERE CopyID IS NOT NULL 
																			GROUP BY VarIDConsolidate, CopyID, CopyTypeID
																			)x 
																	GROUP BY x.VarIDConsolidate
															) y
														GROUP BY VarIDConsolidate
												) usg ON src.VarIDConsolidate = usg.VarIDConsolidate	 
							WHERE src.RNflt = 1					  
				)flt ;
				  
                SET @RC = @@ROWCOUNT ;  


       -- OUTPUT
	   
		-- 	Seconday Output	(Statements + Hashes)  
		   -- CLEAN-UP output tables
		      TRUNCATE TABLE #BRDStatementTypeOutput ;
			  TRUNCATE TABLE #BRDVariableHashAggregate ;

           -- Output for StatementTypes 
			  INSERT INTO #BRDStatementTypeOutput (StatementTypeID, StatementTypeDescription)
			  SELECT st.StatementType AS StatementTypeID, st.Description AS StatementTypeDescription
			  FROM Statements st
			  WHERE EXISTS (SELECT 1 FROM #varstmt61 f WHERE f.StatementTypeID = st.StatementType) ;

           -- Output for Hashes   
              INSERT INTO #BRDVariableHashAggregate (RN, VarHash)
			  SELECT x.RN  ,v1.VariableHash
			  FROM BRD_Variables v1
				  INNER JOIN ( 
							  SELECT  DISTINCT VarIDConsolidate , RN
							  FROM #varrn61
							  WHERE RN BETWEEN  @StartPosition  AND (@StartPosition + @NumberOfRows - 1) 
							 ) x ON v1.VarIDConsolidate = x.VarIDConsolidate
			  WHERE EXISTS (SELECT 1 FROM #varf61 f WHERE f.VarID = v1.VarID) ;




           -- Main Output
				 SELECT    s11.DefinedInCopy 
						  --,s11.DefinitionObjectID 
						  --,s11.DefinitionObjectTypeID 
						  ,rd.ResourceHash AS DefinitionObjectHash  
						  ,rd.ResourceName AS DefinitionObjectName  
						  --,s11.DefinitionObjectPathID 
						  ,pth1.PathStr AS DefinitionObjectPath 
						  ,s11.VarIDConsolidate
						  ,s11.VarPositionStartRow 
						  ,s11.VarPositionEndRow 
						  ,s11.VarPositionStartCol 
						  ,s11.VarPositionEndCol
						  ,COALESCE(cp.CountDistResUsingCopy, 0) AS CountDistResUsingCopy 
						  ,s11.CountDistProgUsingVar  
						  ,s11.CountDistCopyUsingVar
						  ,RN 
						  ,@RC AS NR
				 FROM 
				     (			 
							SELECT  DefinedInCopy ,DefinitionObjectID, DefinitionObjectTypeID, DefinitionObjectPathID 
							       ,VarIDConsolidate ,VarPositionStartRow ,VarPositionEndRow ,VarPositionStartCol ,VarPositionEndCol 
								   ,CountDistProgUsingVar  ,CountDistCopyUsingVar
							       ,RN 
							FROM #varrn61
							WHERE  RN BETWEEN  @StartPosition  AND (@StartPosition + @NumberOfRows - 1) 
					  ) s11
					    INNER JOIN BRD_Paths pth1 ON s11.DefinitionObjectPathID = pth1.PathID
					    INNER JOIN BRD_ResourceDetails rd ON rd.ResourceID = s11.DefinitionObjectID AND rd.ResourceTypeID = s11.DefinitionObjectTypeID  
					    LEFT OUTER JOIN 
					                (
									   SELECT CopyID, CopyTypeID, COUNT(*) AS CountDistResUsingCopy
									   FROM(
											SELECT cr.CopyID, cr.CopyTypeID, cr.ResourceID, cr.ResourceTypeID
											FROM BRD_CopyToResources cr
												 INNER JOIN #varrn61 f ON cr.CopyID = f.DefinitionObjectID AND cr.CopyTypeID = f.DefinitionObjectTypeID
											GROUP BY cr.CopyID, cr.CopyTypeID, cr.ResourceID, cr.ResourceTypeID
										   ) f1 
                                       GROUP BY CopyID, CopyTypeID
									  ) cp ON s11.DefinitionObjectID = cp.CopyID  AND s11.DefinitionObjectTypeID = cp.CopyTypeID	 			
				  ORDER BY RN
				  OPTION(FAST 500) ;

               -- FINAL CLEAN-UP
				  IF OBJECT_ID('tempdb..#varf61')    IS NOT NULL DROP TABLE #varf61 ;
				  IF OBJECT_ID('tempdb..#varstmt61') IS NOT NULL DROP TABLE #varstmt61 ;
				  IF OBJECT_ID('tempdb..#varrn61')   IS NOT NULL DROP TABLE #varrn61 ;

END;
