package com.google.checkstyle.test.chapter4formatting.rule487modifiers;

strictfp abstract class InputModifierOrder //warn
{
	transient private String dontSaveMe; //warn
	
	volatile public int whatImReading; //warn
	
    public volatile boolean sModifierOrderVar = false; // ok

    /**
     * Illegal order of modifiers for methods. Make sure that the
     * first and last modifier from the JLS sequence is used.
     */
    strictfp private void doStuff() //warn
    {
    }

    /** Single annotation without other modifiers */
    @MyAnnotation2 void someMethod()
    {
    }

    /** Illegal order of annotation - must come first */
    private @MyAnnotation2 void someMethod2() //warn
    {
    }

    /** Annotation in middle of other modifiers otherwise in correct order */
    private @MyAnnotation2 strictfp void someMethod3() //warn
    {
    }

    /** Correct order */
    @MyAnnotation2 private strictfp void someMethod4()
    {
    }

    /** Annotation in middle of other modifiers otherwise in correct order */
    @MyAnnotation2 public static @MyAnnotation4 strictfp void someMethod5() //warn
    {
    }
    
    @MyAnnotation2 public static final synchronized strictfp void fooMethod() {}; //ok
    
    strictfp protected final @MyAnnotation2 static synchronized void fooMethod1() {}; //warn
    
    synchronized @MyAnnotation2 strictfp private final static void fooMethod2() {}; //warn
    
    @MyAnnotation2 static synchronized final strictfp protected void fooMethod3() {}; //warn
    
    @MyAnnotation2 strictfp static final synchronized private void fooMethod4() {}; //warn
    
    synchronized final strictfp @MyAnnotation2 static public void fooMethod5() {}; //warn
    
    @MyAnnotation2 static synchronized strictfp private final void fooMethod6() {}; //warn
    
    final strictfp synchronized static protected @MyAnnotation2 void fooMethod7() {}; //warn
    
    @MyAnnotation2 abstract protected void fooMet(); //warn
    
    abstract @MyAnnotation2 public void fooMet1(); //warn

    /** holder for redundant 'public' modifier check. */
    public static interface InputRedundantPublicModifier
    {
        public void a();

        void b();

        abstract void c();

        public float PI_PUBLIC = (float) 3.14;

        final float PI_FINAL = (float) 3.14;

        /** all OK */
        float PI_OK = (float) 3.14;
    }
    final private void method() // warn
    {
    }
}

final class RedundantFinalClass
{
    public final void finalMethod()
    {
    }


    public void method()
    {
    }
    
    protected @MyAnnotation2 static synchronized native void fooMethod(); // warn
    
    static protected @MyAnnotation2 synchronized native void fooMethod1(); // warn
    
    @MyAnnotation2 protected synchronized native void fooMethod2(); // ok
    
    native synchronized protected static @MyAnnotation2 void fooMethod3(); // warn
    
    native @MyAnnotation2 protected static synchronized void fooMethod4(); // warn
    
    public static @MyAnnotation2 synchronized native void fooMethod5(); // warn
    
    synchronized static native @MyAnnotation2 public void fooMethod6(); // warn
    
    static synchronized private native @MyAnnotation2 void fooMethod7(); // warn
}

/** Holder for redundant modifiers of inner implementation */
interface InnerImplementation
{
    InnerImplementation inner =
        new InnerImplementation()
        {
            /** compiler requires 'public' modifier */
            public void method()
            {
            }
        };
    
    void method();
}

class WithInner
{
	/**
	 * Inner class
	 * @author max
	 *
	 */
	class Inner 
	{
		transient private String dontSaveMe; //warn
		
		volatile public int whatImReading; //warn
		
		@MyAnnotation2 protected synchronized native void fooMethod(); // ok
		
	    protected @MyAnnotation2 synchronized native void fooMethod1(); // warn
	    
	    synchronized protected @MyAnnotation2 native void fooMethod2(); // warn
	    
	    native synchronized protected @MyAnnotation2 void fooMethod3(); // warn
	    
	    native @MyAnnotation2 protected synchronized void fooMethod4(); // warn
	    
	    public @MyAnnotation2 synchronized native void fooMethod5(); // warn
	    
	    synchronized native @MyAnnotation2 public void fooMethod6(); // warn
	    
	    synchronized private native @MyAnnotation2 void fooMethod7(); // warn
	    
	    /**
	     * Anonymous class
	     */
	    InnerImplementation foo = new InnerImplementation() {

			
			public void method() {
				// TODO Auto-generated method stub
				
			}
			
			transient private String dontSaveMe; //warn
			
			volatile public int whatImReading; //warn
			
			protected @MyAnnotation2 synchronized native void fooMethod(); // warn
			
		    protected @MyAnnotation2 synchronized native void fooMethod1(); // warn
		    
		    synchronized protected @MyAnnotation2 native void fooMethod2(); // warn
		    
		    native synchronized protected @MyAnnotation2 void fooMethod3(); // warn
		    
		    @MyAnnotation2 protected synchronized native void fooMethod4(); // ok
		    
		    public @MyAnnotation2 synchronized native void fooMethod5(); // warn
		    
		    synchronized native @MyAnnotation2 public void fooMethod6(); // warn
		    
		    synchronized private native @MyAnnotation2 void fooMethod7(); // warn
		};
	}

	/**
	 * Inner abstract class
	 * @author max
	 *
	 */
	abstract class AbsInner
	{
		transient private String dontSaveMe; //warn
		
		volatile public int whatImReading; //warn
		
		@MyAnnotation2 public final synchronized strictfp void fooMethod() {}; //ok
	    
	    strictfp protected final @MyAnnotation2 synchronized void fooMethod1() {}; //warn
	    
	    synchronized @MyAnnotation2 strictfp private final void fooMethod2() {}; //warn
	    
	    @MyAnnotation2 synchronized final strictfp protected void fooMethod3() {}; //warn
	    
	    @MyAnnotation2 strictfp final synchronized private void fooMethod4() {}; //warn
	    
	    synchronized final strictfp @MyAnnotation2 public void fooMethod5() {}; //warn
	    
	    @MyAnnotation2 synchronized strictfp private final void fooMethod6() {}; //warn
	    
	    final strictfp synchronized protected @MyAnnotation2 void fooMethod7() {}; //warn
	    
	    @MyAnnotation2 abstract protected void fooMet(); //warn
	    
	    abstract @MyAnnotation2 public void fooMet1(); //warn
	}
}

/** Holder for redundant modifiers of annotation fields/variables */
@interface Annotation
{
    public String s1 = "";
    final String s2 = "";
    static String s3 = "";
    String s4 = "";
    public String blah();
    abstract String blah2();
}

@interface MyAnnotation2 {
}

@interface MyAnnotation4 {
}

/** Illegal order of modifiers for interface methods */
interface InputModifierOrderInterface
{
    default strictfp void a() { }  //ok

    strictfp default void b() { }  //warn
}
