/// <summary>
        ///     Get general info about candidate for repository
        /// </summary>
        /// <param name="doClass">Class syntax</param>
        private BaseCodeClassGeneratorRepository GetRepository(ClassDeclarationSyntax doClass)
        {
            var className = doClass.Identifier.Text;

            // Get DataAccess attribute from repository model
            var dataAccessAttr = SyntaxAnalysisHelper.GetAttributesAndPropepertiesCollection(doClass).FirstOrDefault(x => x.Name.ToString().Contains(_config.RepositoryAttributeName));

            // common repository info
            var repositoryInfo = new RepositoryInfo()
            {
                RepositorySuffix = _config.RepositorySuffix,
                ClassName = className,
                ClassFullName = _solutionSyntaxWalker.GetFullRepositoryModelName(doClass),
            };

            repositoryInfo.IsTenantRelated = !doClass.BaseTypeExist("ITenantUnrelated");

            // Base class name
            if (doClass.BaseList != null && doClass.BaseList.Types.Any())
            {
                var baseClass = doClass.BaseList.Types.FirstOrDefault(t => _solutionSyntaxWalker.IsBaseClass(t));

                if (baseClass != null)
                {
                    repositoryInfo.BaseClassName = baseClass.ToString();
                }
            }

            #region Repository interface

            // Get implemented interfaces for custom repository (for example - IMenuItemRepository : IRepository<MenuItem>)
            var repositoryInterfaces = _solutionSyntaxWalker.GetInheritedInterfaces(repositoryInfo.GenericRepositoryInterfaceName).ToList();

            var repoInterface = repositoryInterfaces.FirstOrDefault();

            if (repoInterface == null)
            {
                var ret = CreateWithAnalysisError(className, _config.RepositorySuffix, string.Format("Repository interface {0} not found.", repositoryInfo.GenericRepositoryInterfaceName));
                return ret;
            }

            // Repository interface info
            repositoryInfo.RepositoryInterfaceName = _solutionSyntaxWalker.GetTypeNamespace(repoInterface) + "." + repoInterface.Identifier.Text;

            #endregion

            #region Repository model attributes

            #region DataAccess

            var dataAccess = (DataAccessAttribute)dataAccessAttr;

            var tableName = dataAccess.TableName ?? doClass.Identifier.ToString() + 's';
            repositoryInfo.TableName = tableName;

            // Get filters
            var filterKeys = (new[] { dataAccess.FilterKey1, dataAccess.FilterKey2, dataAccess.FilterKey3 })
                .Where(fk => fk != null)
                .Select(fk =>
                {
                    // Filter data may be combined (ItemId, GroupId)
                    var filters = fk.Split(',').Select(f =>
                    {
                        var name = f.Trim();
                        var parameter = doClass.Members.OfType<PropertyDeclarationSyntax>().FirstOrDefault(cp => cp.GetterExist() && cp.SetterExist() && cp.Identifier.Text == name);
                        var fullTypeName = _solutionSyntaxWalker.GetFullPropertyTypeName(parameter);
                        return new ParameterInfo(name, parameter != null ? fullTypeName : null);
                    }).ToList();
                    return new FilterInfo(string.Join("And", fk.Split(',').Select(f => f.Trim())), filters, FilterType.FilterKey);
                });

            repositoryInfo.FilterInfos.AddRange(filterKeys);

            // Common filter - isDeleted, modified
            repositoryInfo.SpecialOptionsIsDeleted = new FilterInfo("IsDeleted", new List<ParameterInfo> {new ParameterInfo("IsDeleted", "bool", Convert.ToString(dataAccess.IsDeleted).FirstSymbolToLower())}, FilterType.FilterKey);
            repositoryInfo.SpecialOptionsModified = new FilterInfo("Modified", new List<ParameterInfo> {new ParameterInfo("Modified", "DateTimeOffset")}, FilterType.FilterKey);

            repositoryInfo.VersionTableName = dataAccess.TableVersion;
            var isVersioning = dataAccess.TableVersion != null;
            repositoryInfo.IsVersioning = isVersioning;

            #endregion

            #endregion

            #region Property attributes

            var properties = doClass.Members.OfType<PropertyDeclarationSyntax>().Where(cp => cp.GetterExist() && cp.SetterExist()).ToList();

            // Add sql column name - skip members marked [DbIgnoreAttribute]
            var elements = properties
                .Where(p => !p.AttributeExist(RepositoryDataModelHelper.DbIgnoreAttributeName))
                .Select(p => p.Identifier.Text);
            repositoryInfo.Elements.AddRange(elements);

            // Primary keys info
            var primaryKeys = properties
                .Where(p => p.AttributeExist(RepositoryDataModelHelper.KeyAttributeName))
                .Select(p =>
                {
                    var fullTypeName = _solutionSyntaxWalker.GetFullPropertyTypeName(p);
                    return new ParameterInfo(p.Identifier.Text, fullTypeName);
                });

            repositoryInfo.PrimaryKeys.AddRange(primaryKeys);

            // Version key
            var versionKey = properties.FirstOrDefault(p => p.AttributeExist(RepositoryDataModelHelper.VesionKeyAttributeName));

            if (versionKey != null)
            {
                var keyName = versionKey.Identifier.Text;
                repositoryInfo.VersionKeyName = keyName;
                var fullTypeName = _solutionSyntaxWalker.GetFullPropertyTypeName(versionKey);

                // add filter parameter
                repositoryInfo.VersionKey = new ParameterInfo(keyName, fullTypeName);
            }

            // Many to many
            var many2ManyInfos = properties
                .Where(p => p.AttributeExist(RepositoryDataModelHelper.DataMany2ManyAttributeName))
                .SelectMany(p => SyntaxAnalysisHelper.GetAttributesAndPropepertiesCollection(p))
                .Where(p => p.Name == RepositoryDataModelHelper.DataMany2ManyAttributeName)
                .Select(p => new Tuple<string, DataMany2ManyAttribute>(p.OwnerElementName, (DataMany2ManyAttribute)p))
                .Select(a =>
                new Many2ManyInfo(a.Item1, a.Item2.ManyToManyEntytyType, a.Item2.EntityType));

            repositoryInfo.Many2ManyInfo.AddRange(many2ManyInfos);

            #endregion

            #region Custom repository

            // Check exist custom repository class
            var customRepository = _solutionSyntaxWalker.FindCustomRepositoryClassByName(doClass.Identifier + _config.RepositorySuffix).FirstOrDefault();
            var customRepoExist = customRepository != null;

            List<MethodInfo> customRepositoryMethods = null;

            // Get custom repository class info
            if (customRepoExist)
            {
                // Custom repository info
                customRepositoryMethods = customRepository.Members.OfType<MethodDeclarationSyntax>()
                    .Select(m => new MethodInfo() { Name = m.Identifier.Text, ReturnType = m.ReturnType.ToString() })
                    .ToList();
                // Check constructor exist
                repositoryInfo.IsConstructorImplemented = customRepository.ConstructorImplementationExist();

                repositoryInfo.RepositoryNamespace = _solutionSyntaxWalker.GetCustomRepositoryNamespace(customRepository);
            }

            var customCacheRepository = _solutionSyntaxWalker.FindCustomRepositoryClassByName(doClass.Identifier + "Cache" + _config.RepositorySuffix).FirstOrDefault();
            var customCacheRepositoryExist = customCacheRepository != null;

            List<MethodInfo> customCacheRepositoryMethods = null;
            // Get custom cache repository class info
            if (customCacheRepositoryExist)
            {
                // Custom repository info
                customCacheRepositoryMethods = customCacheRepository.Members.OfType<MethodDeclarationSyntax>()
                    .Select(m => new MethodInfo() { Name = m.Identifier.Text, ReturnType = m.ReturnType.ToString() })
                    .ToList();

                // Check constructor exist
                repositoryInfo.IsCacheRepositoryConstructorImplemented = customCacheRepository.ConstructorImplementationExist();

                if (repositoryInfo.RepositoryNamespace == null)
                {
                    repositoryInfo.RepositoryNamespace = _solutionSyntaxWalker.GetCustomRepositoryNamespace(customCacheRepository);
                }
            }

            #endregion

            #region Repository methods

            // Search method for implementation
            var repositoryInterfaceMethods = repoInterface.Members.OfType<MethodDeclarationSyntax>()
                .Select(m => new MethodInfo() { Name = m.Identifier.Text, ReturnType = m.ReturnType.ToString() })
                .ToList();

            repositoryInfo.InterfaceMethods.AddRange(repositoryInterfaceMethods);

            if (customRepositoryMethods != null)
            {
                repositoryInfo.CustomRepositoryMethodNames.AddRange(customRepositoryMethods);
            }
            if (customCacheRepositoryMethods != null)
            {
                repositoryInfo.CustomCacheRepositoryMethodNames.AddRange(customCacheRepositoryMethods);
            }

            #endregion

            #region Search required namespace

            if (repositoryInfo.RepositoryNamespace == null)
            {
                repositoryInfo.RepositoryNamespace = _config.DefaultNamespace;
            }

            var requiredNamespaces = new List<string>
            {
                "System",
                "System.Collections.Generic",
                "System.Linq",
                "System.Threading.Tasks"
            };

            repositoryInfo.RequiredNamespaces.Add(RepositoryType.General, requiredNamespaces);

            var repositoryInterfaceNamespace = _solutionSyntaxWalker.GetTypeNamespace(repoInterface);
            repositoryInfo.RequiredNamespaces.Add(RepositoryType.Cache, new List<string> { repositoryInterfaceNamespace });

            #endregion

            var repositoryAndDo = new CodeClassGeneratorRepository
            {
                RepositoryInfo = repositoryInfo
            };
            // return general repository
            return repositoryAndDo;
        }