diff --git a/build.gradle.kts b/build.gradle.kts
index 0bf2dc5fbc76ba94304158c94ccc3b6ba3a4fc84..2139f7552016728fd2aa8f4c379f9ab3bd23510b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -48,12 +48,6 @@ repositories {
     jcenter()
 }
 
-idea {
-    module {
-        generatedSourceDirs.add(file("src/gen"))
-    }
-}
-
 // Configure gradle-intellij-plugin plugin.
 // Read more: https://github.com/JetBrains/gradle-intellij-plugin
 intellij {
@@ -73,6 +67,12 @@ sourceSets {
     }
 }
 
+idea {
+    module {
+        generatedSourceDirs.add(file("src/gen/java"))
+    }
+}
+
 //import org.jetbrains.grammarkit.tasks.*
 //
 grammarKit {
@@ -101,9 +101,28 @@ tasks {
         purgeOldFiles = true
     }
 
+    val generateJastAddAspectLexer = task<GenerateLexer>("generateJastAddAspectLexer") {
+        source = "src/main/grammar/JastAddAspect.flex"
+        targetDir = "src/gen/java/org/jastadd/tooling/aspect/lexer/"
+        targetClass = "JastAddAspectLexer"
+        purgeOldFiles = true
+    }
+
+    // not fully working because of https://github.com/JetBrains/gradle-grammar-kit-plugin/issues/3
+    val generateJastAddAspectParser = task<GenerateParser>("generateJastAddAspectParser") {
+        source = "src/main/grammar/JastAddAspect.bnf"
+        targetRoot = "src/gen/java"
+        pathToParser = "/org/jastadd/tooling/aspect/JastAddAspectParser.java"
+        pathToPsiRoot = "/org/jastadd/tooling/aspect/psi"
+        purgeOldFiles = true
+    }
+
+
     compileJava {
         dependsOn(generateRelAstGrammarLexer)
         dependsOn(generateRelAstGrammarParser)
+        dependsOn(generateRelAstGrammarLexer)
+        dependsOn(generateRelAstGrammarParser)
     }
 
     withType<JavaCompile> {
diff --git a/src/main/grammar/JastAddAspect.bnf b/src/main/grammar/JastAddAspect.bnf
new file mode 100644
index 0000000000000000000000000000000000000000..01b821327f07c06bee036c3e9539d835021ddfbb
--- /dev/null
+++ b/src/main/grammar/JastAddAspect.bnf
@@ -0,0 +1,27 @@
+{
+  parserClass="org.jastadd.tooling.aspect.parser.JastAddAspectParser"
+
+  extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
+
+  psiClassPrefix="JastAddAspect"
+  psiImplClassSuffix="Impl"
+  psiPackage="org.jastadd.tooling.aspect.psi"
+  psiImplPackage="org.jastadd.tooling.aspect.psi.impl"
+
+  elementTypeHolderClass="org.jastadd.tooling.aspect.psi.JastAddAspectTypes"
+  elementTypeClass="org.jastadd.tooling.aspect.JastAddAspectElementType"
+  tokenTypeClass="org.jastadd.tooling.aspect.JastAddAspectTokenType"
+}
+
+jastaddAspectFile ::= (attribute_equation|comment)*
+
+comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT)
+
+attribute_equation ::= EQ java_block
+
+java_block ::= JAVABLOCK
+{
+  implements="org.jastadd.tooling.aspect.psi.JastAddAspectJavaBlockExtension"
+  extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectJavaBlockImplExtension"
+}
+
diff --git a/src/main/grammar/JastAddAspect.flex b/src/main/grammar/JastAddAspect.flex
new file mode 100644
index 0000000000000000000000000000000000000000..fafc09948777b0855329ca2b4776b0a1a393317f
--- /dev/null
+++ b/src/main/grammar/JastAddAspect.flex
@@ -0,0 +1,44 @@
+package org.jastadd.tooling.aspect.lexer;
+
+import com.intellij.lexer.FlexLexer;
+import com.intellij.psi.tree.IElementType;
+import org.jastadd.tooling.aspect.psi.JastAddAspectTypes;
+import com.intellij.psi.TokenType;
+
+%%
+
+%class JastAddAspectLexer
+%implements FlexLexer
+%unicode
+%function advance
+%type IElementType
+%eof{  return;
+%eof}
+
+%{
+  private int counter = 0;
+%}
+
+
+WhiteSpace        = [ ] | \t | \f | \n | \r | \r\n
+//ID                = [a-zA-Z$_][a-zA-Z0-9$_]*
+//MultiLineComment  = [/][*][^*]+[*]+([^*/][^*]*[*]+)*[/]
+//DocComment        = [/][*][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
+//SingleLineComment = [/][/] [^\n\r]* (\n | \r | \r\n)
+NotParenthesis    = [^{}]*
+
+%state JAVA
+
+%%
+
+<YYINITIAL> {
+ {WhiteSpace}+                  {}
+ "EQ"                           { yybegin(YYINITIAL); return JastAddAspectTypes.EQ; }
+ "{"                            { yybegin(JAVA); counter = 1;  }
+}
+
+<JAVA> {
+ {NotParenthesis}               {}
+ "{"                            { counter++; yybegin(JAVA); }
+ "}"                            { counter--; if (counter==0) { yybegin(YYINITIAL); return JastAddAspectTypes.JAVABLOCK; } }
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectElementType.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectElementType.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c15673a1bc53924ea6d497db6dab32381c17372
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectElementType.java
@@ -0,0 +1,13 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class JastAddAspectElementType extends IElementType {
+
+  public JastAddAspectElementType(@NotNull @NonNls String debugName) {
+    super(debugName, JastAddAspectLanguage.INSTANCE);
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFile.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d67846a899164b0ac2cc65ffba532c9785baaa0
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFile.java
@@ -0,0 +1,25 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.extapi.psi.PsiFileBase;
+  import com.intellij.openapi.fileTypes.FileType;
+  import com.intellij.psi.FileViewProvider;
+  import org.jetbrains.annotations.NotNull;
+
+public class JastAddAspectFile extends PsiFileBase {
+
+  public JastAddAspectFile(@NotNull FileViewProvider viewProvider) {
+    super(viewProvider, JastAddAspectLanguage.INSTANCE);
+  }
+
+  @NotNull
+  @Override
+  public FileType getFileType() {
+    return JastAddAttributeFileType.INSTANCE;
+  }
+
+  @Override
+  public String toString() {
+    return "JastAdd Attribute Aspect File";
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFileType.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFileType.java
new file mode 100644
index 0000000000000000000000000000000000000000..ede88303f5adfc9ad4efaf279756af547fb96cc1
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectFileType.java
@@ -0,0 +1,43 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import org.jastadd.tooling.JastAddIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class JastAddAspectFileType extends LanguageFileType {
+
+  public static final JastAddAspectFileType INSTANCE = new JastAddAspectFileType();
+
+  private JastAddAspectFileType() {
+    super(JastAddAspectLanguage.INSTANCE);
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return "JastAdd Aspect";
+  }
+
+  @NotNull
+  @Override
+  public String getDescription() {
+    return "JastAdd file (for inter-type declarations)";
+  }
+
+  @NotNull
+  @Override
+  public String getDefaultExtension() {
+    return "jadd";
+  }
+
+
+  @Nullable
+  @Override
+  public Icon getIcon() {
+    return JastAddIcons.FILE;
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectLanguage.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectLanguage.java
new file mode 100644
index 0000000000000000000000000000000000000000..400caa1ad201c832052d134a4b027219130a248e
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectLanguage.java
@@ -0,0 +1,13 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.lang.Language;
+
+public class JastAddAspectLanguage extends Language {
+
+  public static final JastAddAspectLanguage INSTANCE = new JastAddAspectLanguage();
+
+  private JastAddAspectLanguage() {
+    super("JastAddAspect");
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectParserDefinition.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectParserDefinition.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a749b6acc908ba9305e764fbb83c093fd19e981
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectParserDefinition.java
@@ -0,0 +1,77 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lang.PsiParser;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jastadd.tooling.aspect.lexer.JastAddAspectLexerAdapter;
+import org.jastadd.tooling.aspect.parser.JastAddAspectParser;
+import org.jastadd.tooling.aspect.psi.JastAddAspectTypes;
+import org.jetbrains.annotations.NotNull;
+
+public class JastAddAspectParserDefinition implements ParserDefinition {
+
+  public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE);
+  public static final TokenSet COMMENTS = TokenSet.create(JastAddAspectTypes.COMMENT);
+
+  public static final IFileElementType FILE = new IFileElementType(JastAddAspectLanguage.INSTANCE);
+
+  @NotNull
+  @Override
+  public Lexer createLexer(Project project) {
+    return new JastAddAspectLexerAdapter();
+  }
+
+  @NotNull
+  @Override
+  public TokenSet getWhitespaceTokens() {
+    return WHITE_SPACES;
+  }
+
+  @NotNull
+  @Override
+  public TokenSet getCommentTokens() {
+    return COMMENTS;
+  }
+
+  @NotNull
+  @Override
+  public TokenSet getStringLiteralElements() {
+    return TokenSet.EMPTY;
+  }
+
+  @NotNull
+  @Override
+  public PsiParser createParser(final Project project) {
+    return new JastAddAspectParser();
+  }
+
+  @Override
+  public IFileElementType getFileNodeType() {
+    return FILE;
+  }
+
+  @Override
+  public PsiFile createFile(FileViewProvider viewProvider) {
+    return new JastAddAspectFile(viewProvider);
+  }
+
+  @Override
+  public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) {
+    return SpaceRequirements.MAY;
+  }
+
+  @NotNull
+  @Override
+  public PsiElement createElement(ASTNode node) {
+    return JastAddAspectTypes.Factory.createElement(node);
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAspectTokenType.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectTokenType.java
new file mode 100644
index 0000000000000000000000000000000000000000..54d2601f7a6bb0e21368b9761d7ca3947d353382
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAspectTokenType.java
@@ -0,0 +1,18 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class JastAddAspectTokenType extends IElementType {
+
+  public JastAddAspectTokenType(@NotNull @NonNls String debugName) {
+    super(debugName, JastAddAspectLanguage.INSTANCE);
+  }
+
+  @Override
+  public String toString() {
+    return "JastAddAspectTokenType." + super.toString();
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JastAddAttributeFileType.java b/src/main/java/org/jastadd/tooling/aspect/JastAddAttributeFileType.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd9569ef54a3332cfa9f203ec724b9966c3af964
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JastAddAttributeFileType.java
@@ -0,0 +1,42 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import org.jastadd.tooling.JastAddIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class JastAddAttributeFileType extends LanguageFileType {
+
+  public static final JastAddAttributeFileType INSTANCE = new JastAddAttributeFileType();
+
+  private JastAddAttributeFileType() {
+    super(JastAddAspectLanguage.INSTANCE);
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return "JastAdd Attribute Aspect";
+  }
+
+  @NotNull
+  @Override
+  public String getDescription() {
+    return "JastAdd file (for attributes)";
+  }
+
+  @NotNull
+  @Override
+  public String getDefaultExtension() {
+    return "jrag";
+  }
+
+  @Nullable
+  @Override
+  public Icon getIcon() {
+    return JastAddIcons.FILE;
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/JavaBlockLanguageInjector.java b/src/main/java/org/jastadd/tooling/aspect/JavaBlockLanguageInjector.java
new file mode 100644
index 0000000000000000000000000000000000000000..298ea5999a6675a61912208090b47e614daf400b
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/JavaBlockLanguageInjector.java
@@ -0,0 +1,25 @@
+package org.jastadd.tooling.aspect;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.InjectedLanguagePlaces;
+import com.intellij.psi.LanguageInjector;
+import com.intellij.psi.PsiLanguageInjectionHost;
+import org.jetbrains.annotations.NotNull;
+
+public class JavaBlockLanguageInjector implements LanguageInjector {
+
+  /**
+   * @param host                     PSI element inside which your language will be injected.
+   * @param injectionPlacesRegistrar stores places where injection occurs. <br>
+   *                                 Call its {@link InjectedLanguagePlaces#addPlace(Language, TextRange, String, String)}
+   *                                 method to register particular injection place.
+   *                                 For example, to inject your language in string literal inside quotes, you might want to <br>
+   *                                 {@code injectionPlacesRegistrar.addPlace(myLanguage, new TextRange(1,host.getTextLength()-1))}
+   */
+  @Override
+  public void getLanguagesToInject(@NotNull PsiLanguageInjectionHost host, @NotNull InjectedLanguagePlaces injectionPlacesRegistrar) {
+    injectionPlacesRegistrar.addPlace(JavaLanguage.INSTANCE, new TextRange(0, host.getTextLength()), "class X { public void m(){", "}");
+  }
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/lexer/JastAddAspectLexerAdapter.java b/src/main/java/org/jastadd/tooling/aspect/lexer/JastAddAspectLexerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d87f6a89665a4c361ed7143f574f6729132ca700
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/lexer/JastAddAspectLexerAdapter.java
@@ -0,0 +1,11 @@
+package org.jastadd.tooling.aspect.lexer;
+
+import com.intellij.lexer.FlexAdapter;
+
+public class JastAddAspectLexerAdapter extends FlexAdapter {
+
+  public JastAddAspectLexerAdapter() {
+    super(new JastAddAspectLexer(null));
+  }
+
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/psi/JastAddAspectJavaBlockExtension.java b/src/main/java/org/jastadd/tooling/aspect/psi/JastAddAspectJavaBlockExtension.java
new file mode 100644
index 0000000000000000000000000000000000000000..75b2f3ee760135993ff2094e6bcc3a473c968e63
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/psi/JastAddAspectJavaBlockExtension.java
@@ -0,0 +1,4 @@
+package org.jastadd.tooling.aspect.psi;
+
+public interface JastAddAspectJavaBlockExtension extends com.intellij.psi.PsiLanguageInjectionHost {
+}
diff --git a/src/main/java/org/jastadd/tooling/aspect/psi/impl/JastAddAspectJavaBlockImplExtension.java b/src/main/java/org/jastadd/tooling/aspect/psi/impl/JastAddAspectJavaBlockImplExtension.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1a19e09f95395b05db82bcc3e33e0db00279cf0
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/aspect/psi/impl/JastAddAspectJavaBlockImplExtension.java
@@ -0,0 +1,45 @@
+package org.jastadd.tooling.aspect.psi.impl;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.LiteralTextEscaper;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiLanguageInjectionHost;
+import org.jastadd.tooling.aspect.psi.JastAddAspectJavaBlockExtension;
+import org.jetbrains.annotations.NotNull;
+
+public class JastAddAspectJavaBlockImplExtension extends ASTWrapperPsiElement implements JastAddAspectJavaBlockExtension {
+
+  public JastAddAspectJavaBlockImplExtension(@NotNull ASTNode node) {
+    super(node);
+  }
+
+  /**
+   * @return {@code true} if this instance can accept injections, {@code false} otherwise
+   */
+  @Override
+  public boolean isValidHost() {
+    return true;
+  }
+
+  /**
+   * Update the host element using the provided text of the injected file. It may be required to escape characters from {@code text}
+   * in accordance with the host language syntax. The implementation may delegate to {@link ElementManipulators#handleContentChange(PsiElement, String)}
+   * if {@link ElementManipulator} implementation is registered for this element class.
+   *
+   * @param text text of the injected file
+   * @return the updated instance
+   */
+  @Override
+  public PsiLanguageInjectionHost updateText(@NotNull String text) {
+    return this;
+  }
+
+  /**
+   * @return {@link LiteralTextEscaper} instance which will be used to convert the content of this host element to the content of injected file
+   */
+  @Override
+  public @NotNull LiteralTextEscaper<? extends PsiLanguageInjectionHost> createLiteralTextEscaper() {
+    return LiteralTextEscaper.createSimple(this);
+  }
+}
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 2263a9a4ae142caa59dc341419b0e4437a1cffcf..12c50ebef59cedd7b630ef32981b6c08600359a6 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -57,6 +57,17 @@
             implementation="org.jastadd.tooling.RelAstGrammarLanguageCodeStyleSettingsProvider"/>
 
         <lang.commenter language="JastAddGrammar" implementationClass="org.jastadd.tooling.RelAstGrammarCommenter"/>
+
+        <!-- Attribute/Aspect Language -->
+
+        <fileType name="JastAdd Attribute Aspect" implementationClass="org.jastadd.tooling.aspect.JastAddAttributeFileType"
+                  fieldName="INSTANCE" language="JastAddAspect" extensions="jrag"/>
+        <fileType name="JastAdd Aspect" implementationClass="org.jastadd.tooling.aspect.JastAddAspectFileType"
+                  fieldName="INSTANCE" language="JastAddAspect" extensions="jadd"/>
+
+        <lang.parserDefinition language="JastAddAspect"
+                               implementationClass="org.jastadd.tooling.aspect.JastAddAspectParserDefinition"/>
+        <languageInjector implementation="org.jastadd.tooling.aspect.JavaBlockLanguageInjector"/>
     </extensions>
 
     <actions>