diff --git a/.gitignore b/.gitignore
index 0ff213c4047..5f5d747e730 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ app/pde.jar
 build/macosx/work/
 arduino-core/bin/
 arduino-core/arduino-core.jar
+lib/*
 hardware/arduino/bootloaders/caterina_LUFA/Descriptors.o
 hardware/arduino/bootloaders/caterina_LUFA/Descriptors.lst
 hardware/arduino/bootloaders/caterina_LUFA/Caterina.sym
diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index 1e4819bba34..b0648173c70 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -510,7 +510,10 @@ public Base(String[] args) throws Exception {
         contributionsSelfCheck = new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), contributionInstaller, libraryInstaller);
         new Timer(false).schedule(contributionsSelfCheck, Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD);
       }
-
+      // Load the build settings
+      for(Editor editor: editors){
+        editor.findTab(editor.sketch.getPrimaryFile()).loadBuildSettings(this);
+      }
     } else if (parser.isNoOpMode()) {
       // Do nothing (intended for only changing preferences)
       System.exit(0);
@@ -715,10 +718,8 @@ protected int[] nextEditorLocation() {
     }
   }
 
-
   // .................................................................
 
-
   boolean breakTime = false;
   String[] months = {
           "jan", "feb", "mar", "apr", "may", "jun",
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 2ec29c498cb..9581c2d8d94 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -110,6 +110,34 @@
 import processing.app.tools.MenuScroller;
 import processing.app.tools.Tool;
 
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.BadLocationException;
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.*;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.*;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.ArrayList;
+
+import static processing.app.I18n.tr;
+import static processing.app.Theme.scale;
+
 /**
  * Main editor panel for the Processing Development Environment.
  */
@@ -748,6 +776,10 @@ private JMenu buildToolsMenu() {
     item = new JMenuItem(tr("Get Board Info"));
     item.addActionListener(e -> handleBoardInfo());
     toolsMenu.add(item);
+
+    item = new JMenuItem(tr("Add build settings to .INO file"));
+    item.addActionListener(e -> handleAddBuildSettings());
+    toolsMenu.add(item);
     toolsMenu.addSeparator();
 
     base.rebuildProgrammerMenu();
@@ -2369,6 +2401,21 @@ public void handlePlotter() {
 
   }
 
+  public void handleAddBuildSettings(){
+    final LinkedHashMap<String, String> settingsMap = base.getBoardsCustomMenus().stream().filter(JMenu::isVisible).map((e)->{
+      String setting = e.getText().substring(0, e.getText().indexOf(":"));
+      String value = e.getText().replace(setting + ":", "").replace("\"", "").trim();
+      return new String[]{setting, value};
+    }).collect(LinkedHashMap::new, (map, menu) -> map.put(menu[0], menu[1]), LinkedHashMap::putAll);
+	handleSave(true);
+    Optional<EditorTab> optionalEditorTab = tabs.stream().filter(tab -> tab.getSketch().getSketch().equals(sketch)).findFirst();
+    if(optionalEditorTab.isPresent()){
+      optionalEditorTab.get().setText(sketch.setBuildSettings(sketch, settingsMap));
+      handleSave(true);
+      System.out.println("Build settings header should be added");
+    }
+  }
+
   private void handleBurnBootloader() {
     console.clear();
     EditorConsole.setCurrentEditorConsole(this.console);
diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java
index 5e8f3e4bfcf..b79de0b99c6 100644
--- a/app/src/processing/app/EditorTab.java
+++ b/app/src/processing/app/EditorTab.java
@@ -33,13 +33,12 @@
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.io.IOException;
+import java.lang.annotation.Target;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Optional;
 
-import javax.swing.Action;
-import javax.swing.BorderFactory;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.ToolTipManager;
+import javax.swing.*;
 import javax.swing.border.MatteBorder;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
@@ -57,6 +56,8 @@
 import org.fife.ui.rtextarea.RTextScrollPane;
 
 import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
+import processing.app.debug.TargetBoard;
+import processing.app.debug.TargetPackage;
 import processing.app.helpers.DocumentTextChangeListener;
 import processing.app.syntax.ArduinoTokenMakerFactory;
 import processing.app.syntax.PdeKeywords;
@@ -447,6 +448,42 @@ public void setText(String what) {
     textarea.setLineWrap(textarea.getLineWrap());
   }
 
+
+  /**
+   * This method loads the build settings from the main .INO file and sets the Arduino IDE accordingly
+   */
+  public void loadBuildSettings(Base base){
+
+    LinkedHashMap<String, String> buildSettings = getSketch().getSketch().getBuildSettingsFromProgram(getText());
+
+    Optional<TargetBoard> optionalTargetBoard = BaseNoGui.getTargetPlatform().getBoards().values().stream().filter(board -> board.getPreferences().get("name","").equals("Node32s")).findFirst();
+
+    TargetBoard targetBoard;
+    if(optionalTargetBoard.isPresent()){
+      targetBoard = optionalTargetBoard.get();
+    }else{
+      return;
+    }
+
+    for(String readableName : buildSettings.values()){
+      base.getBoardsCustomMenus().forEach(menuItem -> {
+        Optional<JRadioButtonMenuItem> optionalBoardMenuItem = Arrays.stream(menuItem.getMenuComponents()).filter(subItem->{
+          return subItem instanceof JRadioButtonMenuItem && ((JRadioButtonMenuItem)subItem).getText().equals(readableName) && (((JRadioButtonMenuItem) subItem).getAction().getValue("board") == null || (((JRadioButtonMenuItem) subItem).getAction().getValue("board").equals(targetBoard)));
+          }
+        ).map(subItem-> {
+          return subItem instanceof JRadioButtonMenuItem ? (JRadioButtonMenuItem)subItem : new JRadioButtonMenuItem();
+        }).findFirst();
+        if(optionalBoardMenuItem.isPresent()){
+          optionalBoardMenuItem.get().setSelected(true);
+          optionalBoardMenuItem.get().getAction().actionPerformed(new ActionEvent(this, -1, ""));
+        }else{
+          // TODO Ask the user which value should replace the current value
+
+        }
+      });
+    }
+  }
+
   /**
    * Is the text modified since the last save / load?
    */
diff --git a/arduino-core/src/processing/app/Sketch.java b/arduino-core/src/processing/app/Sketch.java
index 6c417403ec9..c9c42bc7f59 100644
--- a/arduino-core/src/processing/app/Sketch.java
+++ b/arduino-core/src/processing/app/Sketch.java
@@ -139,6 +139,111 @@ public void save() throws IOException {
     }
   }
 
+  private final String buildToolsHeader = "\n/** Arduino IDE Board Tool details\n";
+  private final String buildToolsHeaderEnd = "*/";
+
+  /**
+   * Checks the code for a valid build tool header
+   * @param program The code to scan for the build tools
+   * @return True if the build tool header was found ONE time. Returns false if found MORE than one time, or not found at all.
+   */
+  private boolean containsBuildSettings(String program){
+    return program.contains(buildToolsHeader) && (program.indexOf(buildToolsHeader) == program.lastIndexOf(buildToolsHeader));
+  }
+
+  /**
+   * This function returns the index of the Nth occurrence of the substring in the specified string (http://programming.guide/java/nth-occurrence-in-string.html)
+   * @param str The string to find the Nth occurrence in
+   * @param substr The string to find
+   * @param n The occurrence number you'd like to find
+   * @return
+   */
+  private static int ordinalIndexOf(String str, String substr, int n) {
+    int pos = str.indexOf(substr);
+    while (--n > 0 && pos != -1)
+      pos = str.indexOf(substr, pos + 1);
+    return pos;
+  }
+
+  private String removeBuildSettingsHeader(Sketch sketch){
+    if(sketch.getPrimaryFile().getProgram().contains(buildToolsHeader)) {
+      int headerStartIndex = sketch.getPrimaryFile().getProgram().indexOf(buildToolsHeader);
+      int headerStopIndex = sketch.getPrimaryFile().getProgram().indexOf(buildToolsHeaderEnd);
+      if (headerStartIndex > headerStopIndex) {
+        System.err.println("The build tool header is not the first comment block in your file! Please fix this.");
+        for (int i = 0; i < sketch.getPrimaryFile().getProgram().length(); i++) {
+          if (headerStartIndex < ordinalIndexOf(sketch.getPrimaryFile().getProgram(), buildToolsHeaderEnd, i)) {
+            headerStopIndex = ordinalIndexOf(sketch.getPrimaryFile().getProgram(), buildToolsHeaderEnd, i);
+            break;
+          }
+        }
+      }
+      String header = sketch.getPrimaryFile().getProgram().substring(headerStartIndex, headerStopIndex + buildToolsHeaderEnd.length());
+      return sketch.getPrimaryFile().getProgram().replace(header, "");
+    }
+    return sketch.getPrimaryFile().getProgram();
+  }
+
+  /**
+   * This checks the program code for a valid build tool settings header and returns the LinkedHashMap with the setting name and the value.
+   * The build tools header should not be changed or manipulated by the pre-processor as the pre-processors output may depend on the build tools.
+   * @param program The program code
+   * @return The {@code LinkedHashMap} with the settings and their values of the <b>first</b> header that was found in the program code
+   */
+  public LinkedHashMap<String, String> getBuildSettingsFromProgram(String program){
+    LinkedHashMap<String, String> buildSettings = new LinkedHashMap<>();
+    if(containsBuildSettings(program)){
+        int headerStartIndex = program.indexOf(buildToolsHeader);
+        int headerStopIndex = program.indexOf(buildToolsHeaderEnd);
+        if(headerStartIndex > headerStopIndex){
+          System.err.println("The build tool header is not the first comment block in your file! Please fix this.");
+          for(int i = 0; i < program.length(); i++){
+            if(headerStartIndex < ordinalIndexOf(program, buildToolsHeaderEnd, i)){
+              headerStopIndex = ordinalIndexOf(program, buildToolsHeaderEnd, i);
+              break;
+            }
+          }
+        }
+        String header = program.substring(headerStartIndex + buildToolsHeader.length(), headerStopIndex);
+
+        String[] headerLines = header.split("\n");
+
+        for(int line = 0; line < headerLines.length; line++){
+          String[] setting = headerLines[line].replace("*","").trim().split(": ");
+          if(headerLines[line].indexOf(": ") != (headerLines[line].length() -1)){
+            // The value of the setting is not empty
+            buildSettings.put(setting[0].trim(), setting[1].trim());
+          }else{
+            buildSettings.put(setting[0], "");
+          }
+        }
+    }else{
+      if(!program.contains(buildToolsHeader)){
+        // There are multiple headers, remove them
+        // TODO Create a dialog asking the user to add a build header to the file
+      }
+    }
+
+    return buildSettings;
+  }
+
+  private boolean isBuildSettingsEqual(LinkedHashMap<String,String> first, LinkedHashMap<String, String> second){
+    return first.keySet().containsAll(second.keySet()) && first.values().containsAll(second.values());
+  }
+
+  public String setBuildSettings(Sketch sketch, LinkedHashMap<String, String> buildSettings){
+    if(sketch != this){
+      return "";
+    }
+
+    String customBoardSettingsHeader = buildSettings.entrySet().stream().map(entry-> String.format(" * %s: %s\n", entry.getKey(), entry.getValue())).collect(Collectors.joining("", buildToolsHeader, "*/"));
+    if(!isBuildSettingsEqual(getBuildSettingsFromProgram(sketch.getPrimaryFile().getProgram()),buildSettings)){
+      String headerLessProgram = removeBuildSettingsHeader(sketch);
+      return customBoardSettingsHeader + ((headerLessProgram.charAt(0) == '\n') ? "" : "\n") + headerLessProgram;
+    }
+    return "";
+  }
+
   public int getCodeCount() {
     return files.size();
   }
diff --git a/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino b/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino
index 95c2b6eb0a8..6586e6e69ab 100644
--- a/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino
+++ b/build/shared/examples/01.Basics/BareMinimum/BareMinimum.ino
@@ -1,3 +1,7 @@
+/** Arduino IDE Board Tool details
+ * Board: Arduino/Genuino Uno
+*/
+
 void setup() {
   // put your setup code here, to run once:
 
@@ -6,4 +10,4 @@ void setup() {
 void loop() {
   // put your main code here, to run repeatedly:
 
-}
+}
\ No newline at end of file