/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.royale.compiler.internal.codegen.js.royale;

import java.util.*;

import org.apache.royale.compiler.asdoc.royale.ASDocComment;
import org.apache.royale.compiler.codegen.as.IASEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.common.ASModifier;
import org.apache.royale.compiler.common.DependencyType;
import org.apache.royale.compiler.constants.IASKeywordConstants;
import org.apache.royale.compiler.constants.IASLanguageConstants;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.definitions.IVariableDefinition.VariableClassification;
import org.apache.royale.compiler.definitions.references.IReference;
import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSSessionModel;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.jx.BindableEmitter;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
import org.apache.royale.compiler.internal.scopes.ASScope;
import org.apache.royale.compiler.problems.PublicVarWarningProblem;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.tree.ASTNodeID;
import org.apache.royale.compiler.tree.as.*;
import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
import org.apache.royale.compiler.tree.metadata.IMetaTagsNode;

public class JSRoyaleDocEmitter extends JSGoogDocEmitter
{
    private List<String> classIgnoreList;
    private List<String> ignoreList;
    private List<String> coercionList;
    private Map<String,List<String>> localSettings;
    public boolean emitStringConversions = true;
    private boolean emitExports = true;
    private boolean exportProtected = false;
    
    private boolean suppressClosure = false;

    public JSRoyaleDocEmitter(IJSEmitter emitter)
    {
        super(emitter);
    }

    public List<String> getClassIgnoreList()
    {
        return classIgnoreList;
    }
    
    public void setClassIgnoreList(List<String> value)
    {
        this.classIgnoreList = value;
    }
    
    public Boolean getSuppressClosure() {
        return suppressClosure;
    }
    
    public Boolean getEmitExports() {
        return emitExports;
    }

    @Override
    protected String convertASTypeToJS(String name, String pname)
    {
        if (ignoreList != null)
        {
            if (ignoreList.contains(pname + "." + name))
                return IASLanguageConstants.Object;
        }
        if (coercionList != null)
        {
            if (!coercionList.contains(pname + "." + name))
                return IASLanguageConstants.Object;
        }
        if (classIgnoreList != null)
        {
            if (classIgnoreList.contains(pname + "." + name))
                return IASLanguageConstants.Object;
        }
        if (name.matches("Vector\\.<.*>"))
        {
        	RoyaleJSProject fjp = (RoyaleJSProject)((IASEmitter)emitter).getWalker().getProject();
        	String vectorClassName = fjp.config == null ? null : fjp.config.getJsVectorEmulationClass();
        	if (vectorClassName != null) return vectorClassName;
        	return super.convertASTypeToJS(name, pname);
        }
        
        name = super.convertASTypeToJS(name, pname);
        if (name.equals(IASLanguageConstants.Boolean.toLowerCase())
                || name.equals(IASLanguageConstants.String.toLowerCase())
                || name.equals(IASLanguageConstants.Number.toLowerCase()))
            return name;

        return formatQualifiedName(name);
    }

    private boolean usedNames = false;
    
    @Override
    protected String formatQualifiedName(String name)
    {
    	return ((JSRoyaleEmitter)emitter).formatQualifiedName(name, !usedNames);
    }

    @Override
    public void emitMethodDoc(IFunctionNode node, ICompilerProject project)
    {
    	RoyaleJSProject fjp = (RoyaleJSProject)project;
        boolean keepASDoc = fjp.config != null && fjp.config.getKeepASDoc();
        boolean suppressExports = false;
        if (emitter instanceof JSRoyaleEmitter) {
            suppressExports = ((JSRoyaleEmitter) emitter).getModel().suppressExports;
        }
        if (fjp.config != null)
        {
        	emitExports = !suppressExports && fjp.config.getExportPublicSymbols();
        	exportProtected = !suppressExports && fjp.config.getExportProtectedSymbols();
        }
        else
        {
            emitExports = !suppressExports;
            exportProtected = false;
        }
        emitExports = emitExports && !node.hasModifier(ASModifier.STATIC) && !node.getFunctionClassification().equals(FunctionClassification.PACKAGE_MEMBER);
        exportProtected = exportProtected && !node.hasModifier(ASModifier.STATIC);
        
        coercionList = null;
        ignoreList = null;
        localSettings = null;
        emitStringConversions = true;
        suppressClosure = false;

        IClassDefinition classDefinition = resolveClassDefinition(node);

        ASDocComment asDoc = (ASDocComment) node.getASDocComment();

        if (node instanceof IFunctionNode)
        {
            boolean hasDoc = false;
            Boolean override = false;
            
            if (node.isConstructor())
            {
                if (asDoc != null && keepASDoc)
                    write(changeAnnotations(asDoc.commentNoEnd()));
                else
                    begin();
                hasDoc = true;

                emitJSDocLine(JSEmitterTokens.CONSTRUCTOR);

                IClassDefinition parent = (IClassDefinition) node
                        .getDefinition().getParent();
                IClassDefinition superClass = parent.resolveBaseClass(project);
                String qname = (superClass != null) ? project.getActualPackageName(superClass.getQualifiedName()) : null;

                //support implicit bindable implementation for 'Extends' EventDispatcher:
                if (superClass == null || qname.equals(IASLanguageConstants.Object)) {
                    if (((JSRoyaleEmitter)emitter).getModel().getImplicitBindableImplementation()
                            == JSSessionModel.ImplicitBindableImplementation.EXTENDS) {
                        superClass = (IClassDefinition) project.resolveQNameToDefinition(BindableEmitter.DISPATCHER_CLASS_QNAME);
                        if (superClass == null) {
                            System.out.println(BindableEmitter.DISPATCHER_CLASS_QNAME+" not resolved for implicit super class in "+classDefinition.getQualifiedName());
                        } else qname = BindableEmitter.DISPATCHER_CLASS_QNAME;
                    }
                }

                usedNames = true;
                
                if (superClass != null
                        && !qname.equals(IASLanguageConstants.Object))
                    emitExtends(superClass, superClass.getPackageName());

                IReference[] references = classDefinition
                        .getImplementedInterfaceReferences();

                Boolean sawIEventDispatcher = false;
                Boolean needsIEventDispatcher = ((JSRoyaleEmitter)emitter).getModel().getImplicitBindableImplementation()
                                                == JSSessionModel.ImplicitBindableImplementation.IMPLEMENTS;

                for (IReference iReference : references)
                {
                    ITypeDefinition type = (ITypeDefinition) iReference
                            .resolve(project, (ASScope) classDefinition
                                    .getContainingScope(),
                                    DependencyType.INHERITANCE, true);
                    if (type == null) {
                        System.out.println(iReference.getDisplayString()
                                + " not resolved in "
                                + classDefinition.getQualifiedName());
                    } else {
                        emitImplements(type, project.getActualPackageName(type.getPackageName()));
                    }
                    if (type.getQualifiedName() == BindableEmitter.DISPATCHER_INTERFACE_QNAME)
                        sawIEventDispatcher=true;
                }
                //support implicit bindable implementation for 'implements' IEventDispatcher:
                if (needsIEventDispatcher && !sawIEventDispatcher) {
                    ITypeDefinition type = (ITypeDefinition) project.resolveQNameToDefinition(BindableEmitter.DISPATCHER_INTERFACE_QNAME);
                    if (type == null) {
                        System.out.println(BindableEmitter.DISPATCHER_INTERFACE_QNAME+" not resolved for implicit implementation in "+classDefinition.getQualifiedName());
                    } else {
                        emitImplements(type, project.getActualPackageName(type.getPackageName()));
                    }
                }
                usedNames = false;
            }
            else
            {
                // @override
                override = node.hasModifier(ASModifier.OVERRIDE);

                String ns = node.getNamespace();
                if (ns != null)
                {
                    if (asDoc != null && keepASDoc)
                    {
                        String docText = asDoc.commentNoEnd();
                        String keepToken = JSRoyaleEmitterTokens.EMIT_COERCION
                                .getToken();
                        if (docText.contains(keepToken))
                            loadKeepers(docText);
                        String ignoreToken = JSRoyaleEmitterTokens.IGNORE_COERCION
                        		.getToken();
		                if (docText.contains(ignoreToken))
		                    loadIgnores(docText);
                        String noStringToken = JSRoyaleEmitterTokens.IGNORE_STRING_COERCION
                        		.getToken();
		                if (docText.contains(noStringToken))
		                    emitStringConversions = false;
    
                        String noImplicitComplexCoercion = JSRoyaleEmitterTokens.SUPPRESS_COMPLEX_IMPLICIT_COERCION
                                .getToken();
                        if (docText.contains(noImplicitComplexCoercion))
                            loadLocalSettings(docText, noImplicitComplexCoercion, "true");
		                
                        String noResolveUncertain = JSRoyaleEmitterTokens.SUPPRESS_RESOLVE_UNCERTAIN
                                .getToken();
                        if (docText.contains(noResolveUncertain))
                            loadLocalSettings(docText,noResolveUncertain, "true");
		                
                        String suppressVectorIndexCheck = JSRoyaleEmitterTokens.SUPPRESS_VECTOR_INDEX_CHECK
                                .getToken();
                        if (docText.contains(suppressVectorIndexCheck))
                            loadLocalSettings(docText,suppressVectorIndexCheck, "true");
                        
                        String suppressClosureToken = JSRoyaleEmitterTokens.SUPPRESS_CLOSURE.getToken();
    
                        if (docText.contains(suppressClosureToken))
                            suppressClosure = true;
                        
                        String suppressExport = JSRoyaleEmitterTokens.SUPPRESS_EXPORT.getToken();
                        if (docText.contains(suppressExport)) {
                            emitExports = false;
                            if (IASKeywordConstants.PUBLIC.equals(ns)) // suppress it for reflection data checks:
                                ((JSRoyaleEmitter) (emitter)).getModel().suppressedExportNodes.add(node);
                        }
                        
                        write(changeAnnotations(asDoc.commentNoEnd()));
                    }
                    else
                        begin();
                    emitMethodAccess(node);
                    emitMethodNoCollapse(node, fjp);
                    hasDoc = true;
                }
            }

            if (!override)
            {
	            // @param
	            IParameterNode[] parameters = node.getParameterNodes();
	            for (IParameterNode pnode : parameters)
	            {
	                if (!hasDoc)
	                {
	                    if (asDoc != null && keepASDoc)
	                        write(changeAnnotations(asDoc.commentNoEnd()));
	                    else
	                        begin();
	                    emitMethodAccess(node);
                        emitMethodNoCollapse(node, fjp);
	                    hasDoc = true;
	                }
	
	                IExpressionNode enode = pnode.getNameExpressionNode();
	
	                ITypeDefinition tdef = enode.resolveType(project);
	                if (tdef == null)
	                    continue;
	
	                emitParam(pnode, project.getActualPackageName(tdef.getPackageName()));
	            }
            }
            
            if (!node.isConstructor())
            {
            	if (!override)
            	{
	                // @return
	                String returnType = node.getReturnType();
	                if (returnType != ""
	                        && returnType != ASEmitterTokens.VOID.getToken())
	                {
	                    if (!hasDoc)
	                    {
	                        if (asDoc != null && keepASDoc)
	                            write(changeAnnotations(asDoc.commentNoEnd()));
	                        else
	                            begin();
	                        emitMethodAccess(node);
                            emitMethodNoCollapse(node, fjp);
	                        hasDoc = true;
	                    }
	
	                    ITypeDefinition tdef = ((IFunctionDefinition) node
	                            .getDefinition()).resolveReturnType(project);
	
	                    String packageName = "";
	                    packageName = tdef != null ? tdef.getPackageName() : "";
	
	                    emitReturn(node, project.getActualPackageName(packageName));
	                }
            	}
            	
                if (override)
                {
                    if (!hasDoc)
                    {
                        if (asDoc != null && keepASDoc)
                            write(changeAnnotations(asDoc.commentNoEnd()));
                        else
                            begin();
                        emitMethodAccess(node);
                        emitMethodNoCollapse(node, fjp);
                        hasDoc = true;
                    }

                    emitOverride(node);
                }
            }

            if (hasDoc)
                end();
        }
    }
    
    private void loadLocalSettings(String doc, String settingToken, String defaultSetting)
    {
        if (localSettings == null) localSettings = new HashMap<String, List<String>>();
        int index = doc.indexOf(settingToken);
        List<String> settings = localSettings.containsKey(settingToken) ? localSettings.get(settingToken) : null;
        while (index != -1)
        {
            String setting = doc.substring(index + settingToken.length());
            int endIndex = setting.indexOf("\n");
            setting = setting.substring(0, endIndex);
            setting = setting.trim();
            if (settings == null) {
                settings = new ArrayList<String>();
                localSettings.put(settingToken, settings);
            }
            List<String> settingItems = null;
            if (setting.length() >0) {
                settingItems = Arrays.asList(setting.split("\\s*(,\\s*)+"));
            } else {
                settingItems =  Arrays.asList(defaultSetting);
            }
            for (String settingItem: settingItems) {
                if (settings.contains(settingItem)) {
                    //change the order to reflect the latest addition
                    settings.remove(settingItem);
                }
                settings.add(settingItem);
                //System.out.println("---Adding setting "+settingToken+":"+settingItem);
            }
            index = doc.indexOf(settingToken, index +  settingToken.length());
        }
    }
    
    public boolean hasLocalSetting(String settingToken) {
        if (localSettings == null) return false;
        return (localSettings.keySet().contains(settingToken));
    }
    
    public boolean getLocalSettingAsBoolean(JSRoyaleEmitterTokens token, Boolean defaultValue) {
        return getLocalSettingAsBoolean(token.getToken(), defaultValue);
    }
    
    public boolean getLocalSettingAsBoolean(String settingToken, Boolean defaultValue) {
        boolean setting = defaultValue;
        if (hasLocalSetting(settingToken)) {
            for (String stringVal: localSettings.get(settingToken)) {
                //don't bail out after finding a boolean-ish string val
                //'last one wins'
                if (stringVal.equals("false")) setting = false;
                else if (stringVal.equals("true")) setting = true;
            }
        }
        return setting;
    }
    
    public boolean getLocalSettingIncludesString(JSRoyaleEmitterTokens token, String searchValue) {
        return getLocalSettingIncludesString(token.getToken(), searchValue);
    }
    
    public boolean getLocalSettingIncludesString(String settingToken, String searchValue) {
        boolean hasValue = false;
        if (hasLocalSetting(settingToken)) {
            for (String stringVal: localSettings.get(settingToken)) {
                if (stringVal.equals(searchValue)) {
                    hasValue = true;
                    break;
                }
            }
        }
        return hasValue;
    }

    private void loadIgnores(String doc)
    {
    	ignoreList = new ArrayList<String>();
        String ignoreToken = JSRoyaleEmitterTokens.IGNORE_COERCION.getToken();
        int index = doc.indexOf(ignoreToken);
        while (index != -1)
        {
            String ignore = doc.substring(index + ignoreToken.length());
            int endIndex = ignore.indexOf("\n");
            ignore = ignore.substring(0, endIndex);
            ignore = ignore.trim();
            ignoreList.add(ignore);
            index = doc.indexOf(ignoreToken, index + endIndex);
        }
    }
    
    public boolean hasIgnore(String qName) {
        return ignoreList !=null && qName != null && ignoreList.contains(qName);
    }
    
    private void loadKeepers(String doc)
    {
    	coercionList = new ArrayList<String>();
        String keepToken = JSRoyaleEmitterTokens.EMIT_COERCION.getToken();
        int index = doc.indexOf(keepToken);
        while (index != -1)
        {
            String keeper = doc.substring(index + keepToken.length());
            int endIndex = keeper.indexOf("\n");
            keeper = keeper.substring(0, endIndex);
            keeper = keeper.trim();
            coercionList.add(keeper);
            index = doc.indexOf(keepToken, index + endIndex);
        }
    }

    private String changeAnnotations(String doc)
    {
        // rename these tags so they don't conflict with generated
        // jsdoc tags
        String pass1 = doc.replaceAll("@param", "@asparam");
        String pass2 = pass1.replaceAll("@return", "@asreturn");
        String pass3 = pass2.replaceAll("@private", "@asprivate");
        return pass3;
    }

    public void emitInterfaceMemberDoc(IDefinitionNode node,
            ICompilerProject project)
    {
    	RoyaleJSProject fjp =  (RoyaleJSProject)project;
        boolean keepASDoc = fjp.config != null && fjp.config.getKeepASDoc();
        boolean hasDoc = false;

        ASDocComment asDoc = (ASDocComment) ((IFunctionNode) node)
                .getASDocComment();

        String returnType = ((IFunctionNode) node).getReturnType();
        if (returnType != "" && returnType != ASEmitterTokens.VOID.getToken()) // has return
        {
            if (asDoc != null && keepASDoc)
                write(changeAnnotations(asDoc.commentNoEnd()));
            else
                begin();
            hasDoc = true;

            ITypeDefinition tdef = ((IFunctionDefinition) node.getDefinition())
                    .resolveReturnType(project);

            emitReturn((IFunctionNode) node, tdef.getPackageName());
        }

        IParameterNode[] parameters = ((IFunctionNode) node)
                .getParameterNodes();
        for (IParameterNode pnode : parameters)
        {
            if (!hasDoc)
            {
                if (asDoc != null && keepASDoc)
                    write(changeAnnotations(asDoc.commentNoEnd()));
                else
                    begin();
                hasDoc = true;
            }

            IExpressionNode enode = pnode.getNameExpressionNode();
            emitParam(pnode, enode.resolveType(project).getPackageName());
        }

        if (hasDoc)
            end();
    }

    @Override
    public void emitMethodAccess(IFunctionNode node)
    {
        String ns = node.getNamespace();
        if (ns == IASKeywordConstants.PRIVATE)
        {
            emitPrivate(node);
        }
        else if (ns == IASKeywordConstants.PROTECTED)
        {
            emitProtected(node);
        }
        else // public or custom namespace
        {
            emitPublic(node);
        }
    }

    protected void emitMethodNoCollapse(IFunctionNode node, RoyaleJSProject fjp)
    {
        String ns = node.getNamespace();
        if (ns == IASKeywordConstants.PROTECTED)
        {
            boolean preventRenameProtected = fjp.config != null && fjp.config.getPreventRenameProtectedSymbols();
            if (preventRenameProtected)
            {
                emitNoCollapse(node);
            }
        }
        else if(ns != IASKeywordConstants.PRIVATE) // public or custom namespace
        {
            boolean preventRenamePublic = fjp.config != null && fjp.config.getPreventRenamePublicSymbols();
            if (preventRenamePublic)
            {
                emitNoCollapse(node);
            }
        }
    }

    protected void emitNoCollapse(IDefinitionNode node)
    {
        if (!node.hasModifier(ASModifier.STATIC)
                || node instanceof IAccessorNode
                || IASKeywordConstants.PRIVATE.equals(node.getNamespace()))
        {
            return;
        }
        //dynamically getting/setting a static field won't
        //work properly if it is collapsed in a release build,
        //even when it has been exported
        emitJSDocLine(JSGoogDocEmitterTokens.NOCOLLAPSE);
    }

    @Override
    public void emitFieldDoc(IVariableNode node, IDefinition def, ICompilerProject project)
    {
        RoyaleJSProject fjp =  (RoyaleJSProject)project;
        boolean suppressExports = false;
        if (emitter instanceof JSRoyaleEmitter) {
            suppressExports = ((JSRoyaleEmitter) emitter).getModel().suppressExports;
        }
        if (fjp.config != null)
        {
        	emitExports = !suppressExports && fjp.config.getExportPublicSymbols();
        	exportProtected = !suppressExports && fjp.config.getExportProtectedSymbols();
        }
        else
        {
            emitExports = !suppressExports;
            exportProtected = false;
        }
        emitExports = emitExports && !node.getVariableClassification().equals(VariableClassification.PACKAGE_MEMBER);

        begin();

        String ns = node.getNamespace();
        if (ns == IASKeywordConstants.PRIVATE)
        {
            emitPrivate(node);
        }
        else if (ns == IASKeywordConstants.PROTECTED)
        {
            emitProtected(node);
            boolean preventRename = fjp.config != null && fjp.config.getPreventRenameProtectedSymbols();
            if (preventRename)
            {
                emitNoCollapse(node);
            }
        }
        else
        {
            boolean warnPublicVars = fjp.config != null && fjp.config.getWarnPublicVars() && !fjp.config.getPreventRenamePublicSymbols();
            IMetaTagsNode meta = node.getMetaTags();
            boolean bindable = false;
            if (meta != null)
            {
            	IMetaTagNode tag = meta.getTagByName("Bindable");
            	if (tag != null)
            		bindable = true;
            }
            if (warnPublicVars && !node.isConst() && !bindable && ns.contentEquals("public"))
            {
                IASNode warningNode = node;
                //find "public" child node, which may not be the start of the IVariableNode node because of associated metadata
                int childCount = node.getChildCount();
                int index = 0;
                while (index < childCount) {
                    IASNode child = node.getChild(index);
                    if (child instanceof IIdentifierNode && ((IIdentifierNode) child).getName().equals("public")) {
                        warningNode = child;
                        break;
                    }
                    index++;
                }
                
                if (!suppressedWarning(node, fjp))
                	fjp.getProblems().add(new PublicVarWarningProblem(node.getSourcePath(),
                            node.getStart(), node.getEnd(),
                            warningNode.getLine(), warningNode.getColumn(),
                            node.getEndLine(), node.getEndColumn()));
               

            }
            boolean avoidExport = (node.getASDocComment() instanceof ASDocComment
                    && ((ASDocComment)node.getASDocComment()).commentNoEnd()
                    .contains(JSRoyaleEmitterTokens.SUPPRESS_EXPORT.getToken()));
            
            if (!avoidExport) {
                if (ns.equals(IASKeywordConstants.PUBLIC))
                {
                    emitPublic(node);
                    boolean preventRename = fjp.config != null && fjp.config.getPreventRenamePublicSymbols();
                    if(preventRename)
                    {
                        emitNoCollapse(node);
                    }
                }
            } else {
                //we should also remove it from reflection data... provide a check here for that.
                ((JSRoyaleEmitter)emitter).getModel().suppressedExportNodes.add(node);
            }
        }

        if (node.isConst())
            emitConst(node);

        String packageName = "";
        if (def != null)
            packageName = def.getPackageName();

        emitType(node, project.getActualPackageName(packageName), project);

        end();
    }

    @Override
    public void emitProtected(IASNode node)
    {
    	if (exportProtected)
    		super.emitPublic(node);
    	else
    		super.emitProtected(node);
    }
    
    @Override
    public void emitPublic(IASNode node)
    {
    	if (emitExports)
    		super.emitPublic(node);
    }
    
    private boolean suppressedWarning(IVariableNode node, RoyaleJSProject fjp)
    {
        ASDocComment asDoc = (ASDocComment) node.getASDocComment();
        boolean keepASDoc = fjp.config != null && fjp.config.getKeepASDoc();
        String suppressToken = JSRoyaleEmitterTokens.SUPPRESS_PUBLIC_VAR_WARNING
        .getToken();
        if (asDoc != null && keepASDoc)
        {
            String docText = asDoc.commentNoEnd();
            if (docText.contains(suppressToken))
                return true;
        }
    	IASNode classNode = node.getParent().getParent();
    	if (classNode == null)
    		return false;
    	if (classNode.getNodeID() == ASTNodeID.ClassID)
    	{
    		asDoc = (ASDocComment) ((IClassNode)classNode).getASDocComment();
            if (asDoc != null && keepASDoc)
            {
                String docText = asDoc.commentNoEnd();
                if (docText.contains(suppressToken))
                    return true;
            }
            IClassDefinition cdef = ((IClassNode)classNode).getDefinition();
            if (cdef.isBindable())
            	return true;
            if (!cdef.isPublic())
            	return true;
    	}
    	return false;
    }

}
