/// <summary>
 /// Gets all class declaration nodes in a ProjectWorkspace derived from a specified base type
 /// </summary>
 /// <param name="project">ProjectWorkspace to search</param>
 /// <param name="baseTypeOriginalDefinition">ProjectWorkspace to search</param>
 /// <returns>Collection of class declaration nodes in the project with the specified base type</returns>
 public static IEnumerable <ClassDeclaration> GetClassDeclarationsByBaseType(this ProjectWorkspace project,
                                                                             string baseTypeOriginalDefinition)
 => project.GetAllClassDeclarations().Where(c => c.HasBaseType(baseTypeOriginalDefinition));
        /// <summary>
        /// For Code Based, check for Service Interface and class which implements the same
        /// </summary>
        /// <param name="project">ProjectWorkspace object for Code Based Service</param>
        /// <returns>A tuple of Service Interface and Implementing Class if any, otherwise null</returns>
        public static Tuple <string, string> GetServiceInterfaceAndClass(ProjectWorkspace project)
        {
            Tuple <string, string> serviceInterfaceAndClass;

            var interfaces = project.GetAllInterfaceDeclarations()?.ToList();

            if (interfaces.IsNullOrEmpty())
            {
                return(null);
            }

            var interfacesWithServiceContract = interfaces
                                                .Where(i => i.HasAttribute(Constants.ServiceContractAttribute))
                                                ?.ToList();

            if (interfacesWithServiceContract.IsNullOrEmpty())
            {
                return(null);
            }

            var interfaceWithServiceContractMethods = interfacesWithServiceContract
                                                      .SelectMany(i => i.GetMethodDeclarations())?.ToList();

            if (interfaceWithServiceContractMethods.IsNullOrEmpty())
            {
                return(null);
            }

            var serviceInterfaceMethodWithObjectContract = interfaceWithServiceContractMethods
                                                           .Where(m => m.HasAttribute(Constants.OperationContractAttribute))
                                                           ?.ToList();

            if (!serviceInterfaceMethodWithObjectContract.IsNullOrEmpty())
            {
                var classes = project.GetAllClassDeclarations()?.ToList();
                if (classes.IsNullOrEmpty())
                {
                    return(null);
                }

                foreach (var interfaceWithServiceContract in interfacesWithServiceContract)
                {
                    foreach (var classDeclaration in classes)
                    {
                        if (classDeclaration.InheritsInterface(interfaceWithServiceContract.Identifier))
                        {
                            //Filter out generated Code
                            var IsGeneratedCode = classDeclaration.HasAnnotation(Constants.DebuggerStepThroughAttribute) ||
                                                  classDeclaration.HasAnnotation(Constants.GeneratedCodeAttribute);

                            if (!IsGeneratedCode)
                            {
                                serviceInterfaceAndClass = new Tuple <string, string>(interfaceWithServiceContract.Identifier,
                                                                                      classDeclaration.Identifier);

                                return(serviceInterfaceAndClass);
                            }
                        }
                    }
                }
                return(null);
            }
            else
            {
                return(null);
            }
        }