diff --git a/dockingcore/.gitignore b/dockingcore/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b30fc001ac32c03407491c7be92e4a6a3d432b1b
--- /dev/null
+++ b/dockingcore/.gitignore
@@ -0,0 +1,5 @@
+.project
+.classpath
+.settings
+target
+
diff --git a/dockingcore/license.txt b/dockingcore/license.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9e1f9f00f1257dc2101b6072a6c53ceecd61a7b3
--- /dev/null
+++ b/dockingcore/license.txt
@@ -0,0 +1,502 @@
+     GNU LESSER GENERAL PUBLIC LICENSE
+           Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+          Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+      GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+          NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+         END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library 'Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
\ No newline at end of file
diff --git a/dockingcore/pom.xml b/dockingcore/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..26e67de70a20460871f3edabbc71e5aa60449011
--- /dev/null
+++ b/dockingcore/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>fr.soleil.maven.parent</groupId>
+    <artifactId>java-updated-versions</artifactId>
+    <version>0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>fr.soleil.lib</groupId>
+  <artifactId>DockingCore</artifactId>
+  <version>1.1.4</version>
+  <name>Docking Core</name>
+  <description>A project that defines some common abstractions in docking</description>
+
+  <developers>
+    <developer>
+      <id>girardot</id>
+      <name>Raphaël GIRARDOT</name>
+      <email>raphael.girardot@synchrotron-soleil.fr</email>
+      <organization>SOLEIL</organization>
+      <organizationUrl>http://www.synchrotron-soleil.fr</organizationUrl>
+      <roles>
+        <role>Manager</role>
+      </roles>
+      <timezone>1</timezone>
+    </developer>
+    <developer>
+      <id>viguier</id>
+      <name>Grégory VIGUIER</name>
+      <email>gregory.viguier@synchrotron-soleil.fr</email>
+      <organization>SOLEIL</organization>
+      <organizationUrl>http://www.synchrotron-soleil.fr</organizationUrl>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+      <timezone>1</timezone>
+    </developer>
+  </developers>
+
+  <scm>
+    <connection>scm:git:git@gitlab.synchrotron-soleil.fr:software-control-system/libraries/java/dockingcore.git</connection>
+    <developerConnection>scm:git:git@gitlab.synchrotron-soleil.fr:software-control-system/libraries/java/dockingcore.git</developerConnection>
+    <url>https://gitlab.synchrotron-soleil.fr/software-control-system/libraries/java/dockingcore</url>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <configuration>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>fr.soleil.lib</groupId>
+      <artifactId>BasicUtilities</artifactId>
+    </dependency>
+  </dependencies>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+</project>
diff --git a/dockingcore/src/main/java/fr/soleil/docking/ADockingManager.java b/dockingcore/src/main/java/fr/soleil/docking/ADockingManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..52b157eaca7fd8b49f7b8f84e95ca52506703519
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/ADockingManager.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking;
+
+import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.List;
+import java.util.prefs.Preferences;
+
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+
+import fr.soleil.docking.action.SaveDefaultPerspertiveAction;
+import fr.soleil.docking.exception.DockingException;
+import fr.soleil.docking.perspective.IPerspective;
+import fr.soleil.docking.perspective.IPerspectiveFactory;
+import fr.soleil.docking.view.IViewFactory;
+import fr.soleil.lib.project.ObjectUtils;
+
+/**
+ * A class that prepares docking. Obtain your RootWindow from this class.
+ * 
+ * @author HARDION
+ * @author GIRARDOT
+ */
+public abstract class ADockingManager implements PropertyChangeListener {
+
+    private boolean automaticallySavePerspective = true;
+
+    public boolean isAutomaticallySavePerspective() {
+        return automaticallySavePerspective;
+    }
+
+    public void setAutomaticallySavePerspective(boolean automaticallySavePerspective) {
+        this.automaticallySavePerspective = automaticallySavePerspective;
+    }
+
+    protected IPerspectiveFactory perspectiveFactory = null;
+    protected IViewFactory viewFactory = null;
+
+    public ADockingManager(IViewFactory viewFactory, IPerspectiveFactory perspectiveFactory) {
+        this.viewFactory = viewFactory;
+        this.viewFactory.addPropertyChangeListener(this);
+        this.perspectiveFactory = perspectiveFactory;
+        this.perspectiveFactory.addPropertyChangeListener(this);
+        this.initDockingArea();
+    }
+
+    public List<Action> getActionList() {
+        List<Action> result = null;
+        if (viewFactory != null) {
+            result = viewFactory.getActionList();
+        }
+        if (Boolean.getBoolean("DEBUG")) {
+            result.add(new SaveDefaultPerspertiveAction(this));
+        }
+        return result;
+    }
+
+    /**
+     * initialize this {@link ADockingManager}'s main docking area
+     * 
+     */
+    protected abstract void initDockingArea();
+
+    /**
+     * Returns this {@link ADockingManager}'s main docking area
+     * 
+     * @return A {@link JComponent}
+     */
+    public abstract JComponent getDockingArea();
+
+    /**
+     * Creates a new docking area
+     * 
+     * @param areaBackground The preferred area background. May be <code>null</code>, in which case this
+     *            {@link ADockingManager} chooses the {@link Color} to use
+     * 
+     * @return A {@link JComponent}
+     */
+    public abstract JComponent createNewDockingArea(Color areaBackground);
+
+    /**
+     * Changes the background of a docking area
+     * 
+     * @param dockingArea The docking area
+     * @param areaBackground The background to set
+     */
+    public abstract void setDockingAreaBeackground(JComponent dockingArea, Color areaBackground);
+
+    /**
+     * Returns the perspective factory
+     * 
+     * @return The perspective factory
+     */
+    public IPerspectiveFactory getPerspectiveFactory() {
+        return perspectiveFactory;
+    }
+
+    /**
+     * Returns the view factory
+     * 
+     * @return The view factory
+     */
+    public IViewFactory getViewFactory() {
+        return viewFactory;
+    }
+
+    public void loadPreferences(Preferences prefs) throws DockingException {
+        this.perspectiveFactory.loadPreferences(prefs);
+        this.viewFactory.loadPreferences(prefs);
+        this.applyPerspective(perspectiveFactory.getSelectedPerspective());
+    }
+
+    public void resetLayout() throws DockingException {
+        applyPerspective(perspectiveFactory.getDefault());
+    }
+
+    /**
+     * Applies a perspective to the main docking area
+     * 
+     * @param perspective The perspective to apply
+     * @throws DockingException If a problem occurred while trying to apply the perspective
+     */
+    public void applyPerspective(IPerspective perspective) throws DockingException {
+        applyPerspective(perspective, getDockingArea());
+    }
+
+    /**
+     * Applies a perspective to a docking area
+     * 
+     * @param perspective The perspective to apply
+     * @param dockingArea The docking area
+     * @throws DockingException If a problem occurred while trying to apply the perspective
+     */
+    public abstract void applyPerspective(IPerspective perspective, JComponent dockingArea) throws DockingException;
+
+    public void savePreferences(Preferences prefs) throws DockingException {
+        // Save current Perspective
+        this.updatePerspective(this.perspectiveFactory.getSelectedPerspective());
+
+        // Save Preferences of perspective Factory
+        this.perspectiveFactory.savePreferences(prefs);
+
+        // Save Preferences of Views
+        this.viewFactory.savePreferences(prefs);
+
+    }
+
+    /**
+     * Writes main docking area layout in a perspective
+     * 
+     * @param perspective The perspective
+     */
+    protected void updatePerspective(IPerspective perspective) {
+        try {
+            updatePerspective(perspective, getDockingArea());
+        } catch (DockingException e) {
+            JOptionPane.showMessageDialog(getDockingArea(), e.getMessage() + " (see traces)", getClass()
+                    .getSimpleName() + " Docking - Error", JOptionPane.ERROR_MESSAGE);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Writes a docking area layout in a perspective
+     * 
+     * @param perspective The perspective
+     * @param dockingArea The docking area
+     * @throws DockingException If a problem occurred while writing the layout
+     */
+    public abstract void updatePerspective(IPerspective perspective, JComponent dockingArea) throws DockingException;
+
+    public void saveDefault(File file) throws DockingException {
+        this.updatePerspective(this.perspectiveFactory.getSelectedPerspective());
+        this.perspectiveFactory.saveSelected(file);
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt != null) {
+            if (ObjectUtils.sameObject(perspectiveFactory, evt.getSource())) {
+                if (IPerspectiveFactory.SELECTED_PERSPECTIVE.equals(evt.getPropertyName())) {
+                    IPerspective oldd = (IPerspective) evt.getOldValue();
+                    IPerspective neww = (IPerspective) evt.getNewValue();
+                    try {
+                        if (automaticallySavePerspective) {
+                            this.updatePerspective(oldd);
+                        }
+                        this.applyPerspective(neww);
+                    } catch (DockingException e) {
+                        e.printStackTrace();
+                    }
+                }
+            } else if (ObjectUtils.sameObject(viewFactory, evt.getSource())) {
+                if (IViewFactory.VIEWS.equals(evt.getPropertyName())) {
+                    this.updateViews(evt);
+                }
+            }
+        }
+    }
+
+    protected abstract void updateViews(PropertyChangeEvent evt);
+
+    public void saveSelectedPerspective() throws DockingException {
+        this.updatePerspective(this.perspectiveFactory.getSelectedPerspective());
+    }
+
+    /**
+     * Enable the docking or not If the docking is disable, the inherit class must disable all
+     * functionality of the docking. I must be comparable to a JPanel composed by JtabbedPane,
+     * JSplitPane etc...
+     * 
+     * @param enabledDocking
+     */
+    public void setEnabledDocking(boolean enabledDocking) {
+        setEnabledDocking(enabledDocking, getDockingArea());
+    }
+
+    /**
+     * Get the Enabled Docking property
+     * 
+     * @return true if the docking is enabled
+     */
+    public boolean isEnabledDocking() {
+        return isEnabledDocking(getDockingArea());
+    }
+
+    /**
+     * Enable the docking or not in a docking area. If the docking is disable, the inherit class must disable all
+     * functionality of the docking for the docking area. I must be comparable to a JPanel composed by JtabbedPane,
+     * JSplitPane etc...
+     * 
+     * @param enabledDocking Whetehr to enable docking
+     * @param dockingArea The docking area for which to enable/disable docking
+     */
+    public abstract void setEnabledDocking(boolean enabledDocking, JComponent dockingArea);
+
+    /**
+     * Get the Enabled Docking property for a docking area
+     * 
+     * @param dockingArea The docking area to test
+     * 
+     * @return true if the docking is enabled
+     */
+    public abstract boolean isEnabledDocking(JComponent dockingArea);
+
+    /**
+     * Returns whether a view, once closed, is sure to be restored at the exact previous position once shown again
+     * 
+     * @return A <code>boolean</code>
+     */
+    public abstract boolean canRestoreExactViewPosition();
+
+    /**
+     * Configures a docking area to accept or not component undocking (window creation outside of the docking area for
+     * given component)
+     * 
+     * @param enabled Whether to accept component undocking
+     * @param dockingArea The concerned docking area
+     */
+    public abstract void setUndockEnabled(boolean enabled, JComponent dockingArea);
+
+    /**
+     * Configures main docking area to accept or not component undocking
+     * 
+     * @param enabled Whether to accept component undocking
+     */
+    public void setUndockEnabled(boolean enabled) {
+        setUndockEnabled(enabled, getDockingArea());
+    }
+
+    /**
+     * Returns whether a docking area accepts component undocking (window creation outside of the docking area for
+     * given component)
+     * 
+     * @param dockingArea The concerned docking area
+     * @return A <code>boolean</code>
+     */
+    public abstract boolean isUndockEnabled(JComponent dockingArea);
+
+    /**
+     * Returns whether main docking area accepts component undocking
+     * 
+     * @return A <code>boolean</code>
+     */
+    public boolean isUndockEnabled() {
+        return isUndockEnabled(getDockingArea());
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/action/NewPerspectiveAction.java b/dockingcore/src/main/java/fr/soleil/docking/action/NewPerspectiveAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb959f88ec9e5e6d04a928c653874693a75e3adc
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/action/NewPerspectiveAction.java
@@ -0,0 +1,67 @@
+/*
+ * Created on 10 juin 2005
+ * with Eclipse
+ */
+package fr.soleil.docking.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JOptionPane;
+import javax.swing.KeyStroke;
+
+import fr.soleil.docking.perspective.IPerspective;
+import fr.soleil.docking.perspective.IPerspectiveFactory;
+
+public class NewPerspectiveAction extends AbstractAction {
+
+    private static final long serialVersionUID = -3295304363885371351L;
+
+    private final IPerspectiveFactory factory;
+
+    public NewPerspectiveAction(IPerspectiveFactory factory) {
+        super();
+
+        this.factory = factory;
+
+        // This is an instance initializer; it is executed just after the
+        // constructor of the superclass is invoked
+
+        // The following values are completely optional
+        putValue(NAME, "New");
+        // Set tool tip text
+        putValue(SHORT_DESCRIPTION, "New Perspective");
+
+        // This text is not directly used by any Swing component;
+        // however, this text could be used in a help system
+        putValue(LONG_DESCRIPTION, "Adding a new perspective");
+
+        // Set an icon
+        // Icon icon = new ImageIcon("icon.gif");
+        // putValue(Action.SMALL_ICON, icon);
+
+        // Set a mnemonic character. In most look and feels, this causes the
+        // specified character to be underlined This indicates that if the component
+        // using this action has the focus and In some look and feels, this causes
+        // the specified character in the label to be underlined and
+        putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_N));
+
+        // Set an accelerator key; this value is used by menu items
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl shift N"));
+
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        IPerspective current = factory.getSelectedPerspective();
+        String result = JOptionPane.showInputDialog("Enter the name of the new perspective");
+        if ((result != null) && (!result.trim().isEmpty())) {
+            IPerspective p = factory.createPerspective(result);
+            byte[] array = current.getByteArray();
+            byte[] copy = (array == null ? null : array.clone());
+            p.setByteArray(copy);
+            factory.setSelectedPerspective(p);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/dockingcore/src/main/java/fr/soleil/docking/action/RemovePerspectiveAction.java b/dockingcore/src/main/java/fr/soleil/docking/action/RemovePerspectiveAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ac13e42707acdc45534681ec4d1cfdb50161b54
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/action/RemovePerspectiveAction.java
@@ -0,0 +1,64 @@
+/*
+ * Created on 10 juin 2005
+ * with Eclipse
+ */
+package fr.soleil.docking.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JOptionPane;
+import javax.swing.KeyStroke;
+
+import fr.soleil.docking.perspective.IPerspective;
+import fr.soleil.docking.perspective.IPerspectiveFactory;
+
+public class RemovePerspectiveAction extends AbstractAction {
+
+    private static final long serialVersionUID = 4431356413525394103L;
+
+    private final IPerspectiveFactory factory;
+
+    public RemovePerspectiveAction(IPerspectiveFactory factory) {
+        super();
+
+        this.factory = factory;
+
+        // This is an instance initializer; it is executed just after the
+        // constructor of the superclass is invoked
+
+        // The following values are completely optional
+        putValue(NAME, "Remove");
+        // Set tool tip text
+        putValue(SHORT_DESCRIPTION, "Remove Perspective");
+
+        // This text is not directly used by any Swing component;
+        // however, this text could be used in a help system
+        putValue(LONG_DESCRIPTION, "Removing a perspective");
+
+        // Set an icon
+        // Icon icon = new ImageIcon("icon.gif");
+        // putValue(Action.SMALL_ICON, icon);
+
+        // Set a mnemonic character. In most look and feels, this causes the
+        // specified character to be underlined This indicates that if the component
+        // using this action has the focus and In some look and feels, this causes
+        // the specified character in the label to be underlined and
+        putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_R));
+
+        // Set an accelerator key; this value is used by menu items
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl shift R"));
+
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        IPerspective result = (IPerspective) JOptionPane.showInputDialog(null, "Select the perspective to remove",
+                "Remove perspective", JOptionPane.PLAIN_MESSAGE, null, factory.getPerspectives(),
+                factory.getSelectedPerspective());
+        if (result != null) {
+            factory.removePerspective(result);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/dockingcore/src/main/java/fr/soleil/docking/action/SaveDefaultPerspertiveAction.java b/dockingcore/src/main/java/fr/soleil/docking/action/SaveDefaultPerspertiveAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0f94813eb4e89a6c3eb321cd57777be778918ec
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/action/SaveDefaultPerspertiveAction.java
@@ -0,0 +1,75 @@
+/*
+ * Created on 10 juin 2005
+ * with Eclipse
+ */
+package fr.soleil.docking.action;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.File;
+
+import javax.swing.AbstractAction;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
+import fr.soleil.docking.ADockingManager;
+import fr.soleil.lib.project.ObjectUtils;
+
+public class SaveDefaultPerspertiveAction extends AbstractAction {
+
+    private static final long serialVersionUID = -5058889377558638684L;
+
+    private final ADockingManager dockingManager;
+
+    public SaveDefaultPerspertiveAction(ADockingManager manager) {
+        super();
+        this.dockingManager = manager;
+        // This is an instance initializer; it is executed just after the
+        // constructor of the superclass is invoked
+
+        // The following values are completely optional
+        putValue(NAME, "Save Default");
+        // Set tool tip text
+        putValue(SHORT_DESCRIPTION, "Save this perspective to file system");
+
+        // This text is not directly used by any Swing component;
+        // however, this text could be used in a help system
+        putValue(LONG_DESCRIPTION, "Save this perspective to file system");
+
+        // Set an icon
+        // Icon icon = new ImageIcon("icon.gif");
+        // putValue(Action.SMALL_ICON, view.getIcon());
+
+        // Set a mnemonic character. In most look and feels, this causes the
+        // specified character to be underlined This indicates that if the component
+        // using this action has the focus and In some look and feels, this causes
+        // the specified character in the label to be underlined and
+        // putValue(Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_N));
+
+        // Set an accelerator key; this value is used by menu items
+        // putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("alt shift N"));
+
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent evt) {
+        JFileChooser chooser = new JFileChooser();
+
+        if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = chooser.getSelectedFile();
+            try {
+                if (!file.exists())
+                    file.createNewFile();
+                dockingManager.saveDefault(file);
+            } catch (Exception e) {
+                JOptionPane.showMessageDialog((Component) evt.getSource(), ObjectUtils.printStackTrace(e));
+            }
+        }
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/dockingcore/src/main/java/fr/soleil/docking/action/SelectPerspectiveAction.java b/dockingcore/src/main/java/fr/soleil/docking/action/SelectPerspectiveAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..518d731e7f2fb0316bd156ef7dcf1f8cbbc171ad
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/action/SelectPerspectiveAction.java
@@ -0,0 +1,80 @@
+/*
+ * Created on 10 juin 2005
+ * with Eclipse
+ */
+package fr.soleil.docking.action;
+
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.KeyStroke;
+
+import fr.soleil.docking.perspective.IPerspective;
+import fr.soleil.docking.perspective.IPerspectiveFactory;
+import fr.soleil.lib.project.ObjectUtils;
+
+public class SelectPerspectiveAction extends AbstractAction implements PropertyChangeListener {
+
+    private static final long serialVersionUID = 6402682388656946588L;
+
+    private final IPerspectiveFactory factory;
+    private final IPerspective perspective;
+
+    public SelectPerspectiveAction(IPerspectiveFactory factory, IPerspective perspective) {
+        super();
+
+        this.factory = factory;
+        this.factory.addPropertyChangeListener(this);
+        this.perspective = perspective;
+
+        // This is an instance initializer; it is executed just after the
+        // constructor of the superclass is invoked
+
+        // The following values are completely optional
+        putValue(NAME, perspective.getName());
+        // Set tool tip text
+        putValue(SHORT_DESCRIPTION, "Select " + perspective.getName());
+
+        // This text is not directly used by any Swing component;
+        // however, this text could be used in a help system
+        putValue(LONG_DESCRIPTION, "Select " + perspective.getName() + " as current perspective");
+
+        // Set an icon
+        // Icon icon = new ImageIcon("icon.gif");
+        // putValue(Action.SMALL_ICON, icon);
+
+        // Set a mnemonic character. In most look and feels, this causes the
+        // specified character to be underlined This indicates that if the component
+        // using this action has the focus and In some look and feels, this causes
+        // the specified character in the label to be underlined and
+        putValue(MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_N));
+
+        // Set an accelerator key; this value is used by menu items
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl shift N"));
+
+        // Set selected
+        putValue(SELECTED_KEY, this.factory.getSelectedPerspective() == this.perspective);
+
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        factory.setSelectedPerspective(perspective);
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt != null) {
+            if (IPerspectiveFactory.SELECTED_PERSPECTIVE.equals(evt.getPropertyName())) {
+                if (ObjectUtils.sameObject(evt.getNewValue(), this.perspective)) {
+                    putValue(SELECTED_KEY, true);
+                } else {
+                    putValue(SELECTED_KEY, false);
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/dockingcore/src/main/java/fr/soleil/docking/action/ViewAction.java b/dockingcore/src/main/java/fr/soleil/docking/action/ViewAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..02aa2b9fcb9df0801d98bd9fee4e1781b728f517
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/action/ViewAction.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import fr.soleil.docking.view.IView;
+
+public class ViewAction extends AbstractAction {
+
+    private static final long serialVersionUID = 2102313023512752659L;
+
+    private final IView view;
+
+    public ViewAction(IView view) {
+        super();
+        this.view = view;
+        // This is an instance initializer; it is executed just after the
+        // constructor of the superclass is invoked
+
+        // The following values are completely optional
+        putValue(NAME, view.getTitle());
+        // Set tool tip text
+        putValue(SHORT_DESCRIPTION, view.getTitle());
+
+        // This text is not directly used by any Swing component;
+        // however, this text could be used in a help system
+        putValue(LONG_DESCRIPTION, view.getTitle());
+
+        // Set an icon
+        // Icon icon = new ImageIcon("icon.gif");
+        putValue(SMALL_ICON, view.getIcon());
+
+        // Set a mnemonic character. In most look and feels, this causes the
+        // specified character to be underlined This indicates that if the component
+        // using this action has the focus and In some look and feels, this causes
+        // the specified character in the label to be underlined and
+        // putValue(Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_N));
+
+        // Set an accelerator key; this value is used by menu items
+        // putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("alt shift N"));
+
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (!view.isVisible()) {
+            view.setVisible(true);
+        } else {
+            view.setVisible(false);
+        }
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return view.isEnabled();
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/component/PerspectiveMenu.java b/dockingcore/src/main/java/fr/soleil/docking/component/PerspectiveMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..676c5b26027ec6a3c1801bcd23d1f7b641e46fcc
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/component/PerspectiveMenu.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.component;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+
+import fr.soleil.docking.action.NewPerspectiveAction;
+import fr.soleil.docking.perspective.IPerspectiveFactory;
+
+public class PerspectiveMenu extends javax.swing.JMenu implements PropertyChangeListener {
+
+    private static final long serialVersionUID = -6492472049072385936L;
+
+    protected IPerspectiveFactory factory;
+
+    public PerspectiveMenu(IPerspectiveFactory factory) {
+        super();
+        this.setText("Perspective");
+        this.factory = factory;
+        factory.addPropertyChangeListener(this);
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt != null) {
+            if (evt.getSource() instanceof IPerspectiveFactory) {
+                if (IPerspectiveFactory.PERSPECTIVES.equals(evt.getPropertyName())) {
+                    // TODO
+                }
+            }
+        }
+    }
+
+    @Override
+    public JMenuItem add(Action a) {
+        if (a instanceof NewPerspectiveAction) {
+            this.addSeparator();
+        }
+        return super.add(a);
+    }
+
+    @Override
+    public void setPopupMenuVisible(boolean flag) {
+        if (flag) {
+            this.removeAll();
+            List<Action> actions = factory.getActionList();
+            for (Action action : actions) {
+                add(action);
+                // JRadioButtonMenuItem item = (JRadioButtonMenuItem) this.add(action);
+                // Boolean b = (Boolean) action.getValue("SELECTED_KEY");
+                // if (b != null) {
+                // item.setSelected(b);
+                // }
+            }
+        }
+        super.setPopupMenuVisible(flag);
+    }
+
+    @Override
+    protected JMenuItem createActionComponent(Action a) {
+        JMenuItem mi = new JRadioButtonMenuItem() {
+            private static final long serialVersionUID = -3334691946468856486L;
+
+            @Override
+            protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
+                PropertyChangeListener pcl = createActionChangeListener(this);
+                if (pcl == null) {
+                    pcl = super.createActionPropertyChangeListener(a);
+                }
+                return pcl;
+            }
+
+        };
+        mi.setHorizontalTextPosition(JButton.TRAILING);
+        mi.setVerticalTextPosition(JButton.CENTER);
+        return mi;
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/event/ViewEvent.java b/dockingcore/src/main/java/fr/soleil/docking/event/ViewEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7de249234005b2ec1cadcc01f650e7069fb1137
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/event/ViewEvent.java
@@ -0,0 +1,53 @@
+package fr.soleil.docking.event;
+
+import java.util.EventObject;
+
+import fr.soleil.docking.view.IView;
+
+/**
+ * An {@link EventObject} that describes the changes in an {@link IView}
+ * 
+ * @author GIRARDOT
+ */
+public class ViewEvent extends EventObject {
+
+    private static final long serialVersionUID = 1725475008782759147L;
+
+    /**
+     * An <code>int</code> used to notify that the associated view was closed
+     */
+    public static final int VIEW_CLOSED = 0;
+    /**
+     * An <code>int</code> used to notify that the associated view gained the focus
+     */
+    public static final int FOCUS_GAINED = 1;
+    /**
+     * An <code>int</code> used to notify that the associated view lost the focus
+     */
+    public static final int FOCUS_LOST = 2;
+
+    protected final int reason;
+
+    public ViewEvent(IView source, int reason) {
+        super(source);
+        this.reason = reason;
+    }
+
+    @Override
+    public IView getSource() {
+        return (IView) super.getSource();
+    }
+
+    /**
+     * Returns the reason of the changes
+     * 
+     * @return An <code>int</code>
+     * @see #VIEW_CLOSED
+     * @see #FOCUS_GAINED
+     * @see #FOCUS_LOST
+     */
+    public int getReason() {
+        return reason;
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/exception/DockingException.java b/dockingcore/src/main/java/fr/soleil/docking/exception/DockingException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5214dc82a313368625b11d1fb965d58c97c29748
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/exception/DockingException.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.exception;
+
+/**
+ * An Exception thrown in case of problems with docking
+ * 
+ * @author girardot
+ */
+public class DockingException extends Exception {
+
+    private static final long serialVersionUID = 5753611012723925293L;
+
+    public DockingException() {
+        super();
+    }
+
+    public DockingException(String message) {
+        super(message);
+    }
+
+    public DockingException(Throwable cause) {
+        super(cause);
+    }
+
+    public DockingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/listener/IViewListener.java b/dockingcore/src/main/java/fr/soleil/docking/listener/IViewListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..e52ec107252656eafccf79fae5450961902fe75c
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/listener/IViewListener.java
@@ -0,0 +1,22 @@
+package fr.soleil.docking.listener;
+
+import java.util.EventListener;
+
+import fr.soleil.docking.event.ViewEvent;
+import fr.soleil.docking.view.IView;
+
+/**
+ * An {@link EventListener} that listens to the changes in an {@link IView}
+ * 
+ * @author GIRARDOT
+ */
+public interface IViewListener extends EventListener {
+
+    /**
+     * Notifies this {@link IViewListener} for some changes in an {@link IView}
+     * 
+     * @param event The {@link ViewEvent} that describes the concerned {@link IView} and changes
+     */
+    public void viewChanged(ViewEvent event);
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/listener/ViewListenerDelegate.java b/dockingcore/src/main/java/fr/soleil/docking/listener/ViewListenerDelegate.java
new file mode 100644
index 0000000000000000000000000000000000000000..79b9970bcd462743002cb8153383b27ea463971d
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/listener/ViewListenerDelegate.java
@@ -0,0 +1,69 @@
+package fr.soleil.docking.listener;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.WeakHashMap;
+
+import fr.soleil.docking.event.ViewEvent;
+
+/**
+ * A class delegated to {@link IViewListener}s management
+ * 
+ * @author GIRARDOT
+ */
+public class ViewListenerDelegate {
+
+    protected final Collection<IViewListener> listeners;
+
+    public ViewListenerDelegate() {
+        listeners = Collections.newSetFromMap(new WeakHashMap<IViewListener, Boolean>());
+    }
+
+    /**
+     * Warns all {@link IViewListener}s for some changes
+     * 
+     * @param event The {@link ViewEvent} that describes the changes
+     */
+    public void warnListeners(ViewEvent event) {
+        List<IViewListener> copy;
+        synchronized (listeners) {
+            copy = new ArrayList<IViewListener>(listeners.size());
+            copy.addAll(listeners);
+        }
+        for (IViewListener listener : copy) {
+            if (listener != null) {
+                listener.viewChanged(event);
+            }
+        }
+        copy.clear();
+    }
+
+    /**
+     * Adds a new {@link IViewListener}
+     * 
+     * @param listener the {@link IViewListener} to add
+     */
+    public void addViewListener(final IViewListener listener) {
+        if (listener != null) {
+            synchronized (listeners) {
+                listeners.add(listener);
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link IViewListener}
+     * 
+     * @param listener The {@link IViewListener} to remove
+     */
+    public void removeViewListener(IViewListener listener) {
+        if (listener != null) {
+            synchronized (listeners) {
+                listeners.remove(listener);
+            }
+        }
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/FilePerspective.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/FilePerspective.java
new file mode 100644
index 0000000000000000000000000000000000000000..14ac410b574e7eec19653f7aeed4c7431fbe3fae
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/FilePerspective.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.perspective;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Deprecated
+public class FilePerspective extends Perspective {
+
+    public FilePerspective(String name, File file) throws IOException {
+        super(name);
+        if ((file != null) && (file.isFile())) {
+            InputStream in = new FileInputStream(file);
+            if (in != null) {
+                byteArray = PerspectiveFactory.readByteArray(in);
+            }
+        }
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspective.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspective.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b06d53a187766ff041ee1516839b2959f1fbe75
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspective.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.perspective;
+
+/**
+ * Objects that implement this interface should know where to put each dockable component.
+ * 
+ * @author Hardion
+ * @author GIRARDOT
+ */
+public interface IPerspective {
+
+    public String getName();
+
+    /**
+     * @return the byteArray
+     */
+    public byte[] getByteArray();
+
+    /**
+     * @param byteArray the byteArray to set
+     */
+    public void setByteArray(byte[] byteArray);
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspectiveFactory.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspectiveFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..26f10f0f9f867e8b3bad81b0b2544c5bd012f5a2
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/IPerspectiveFactory.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.perspective;
+
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.List;
+import java.util.prefs.Preferences;
+
+import javax.swing.Action;
+
+import fr.soleil.docking.exception.DockingException;
+
+/**
+ * Factory that manages Perspectives
+ * 
+ * @author Hardion
+ * @author GIRARDOT
+ */
+public interface IPerspectiveFactory {
+
+    public static final String SELECTED_PERSPECTIVE = "selectedPerspective";
+    public static final String PERSPECTIVES = "perspectives";
+
+    /**
+     * Returns the Perspective associated with this id.
+     * 
+     * @param id The id of the desired Perspective.
+     * @return The Perspective associated with this id.
+     */
+    public IPerspective getPerspective(Object id);
+
+    /**
+     * Returns the selected IPerspective
+     * 
+     * @return The selected IPerspective
+     */
+    public IPerspective getSelectedPerspective();
+
+    /**
+     * Sets the selected IPerspective
+     * 
+     * @param selectedPerspective The IPerspective to set as selected
+     */
+    public void setSelectedPerspective(IPerspective selectedPerspective);
+
+    public void setSelectedPerspective(String perspective);
+
+    public void loadPreferences(Preferences prefs);
+
+    public void savePreferences(Preferences prefs);
+
+    public List<Action> getActionList();
+
+    public void saveSelected(File file) throws DockingException;
+
+    public void savePerspective(File file, IPerspective perspective) throws DockingException;
+
+    public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener);
+
+    public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener);
+
+    public IPerspective getDefault();
+
+    public IPerspective createPerspective(final String name);
+
+    public IPerspective removePerspective(IPerspective perspective);
+
+    public IPerspective[] getPerspectives();
+
+    public IPerspective loadPerspectiveFromFile(File perspectiveFile, String perpectiveName) throws DockingException;
+
+    public void loadFileInPerspective(File perspectiveFile, IPerspective perspective) throws DockingException;
+
+    public IPerspective loadPerspectiveFromResource(String resource, String perpectiveName) throws DockingException;
+
+    public void loadResourceInPerspective(String resource, IPerspective perspective) throws DockingException;
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/Perspective.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/Perspective.java
new file mode 100644
index 0000000000000000000000000000000000000000..89ad8d9bf266ef6c9b6d9a95837378e54662d656
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/Perspective.java
@@ -0,0 +1,36 @@
+/**
+ * 
+ */
+package fr.soleil.docking.perspective;
+
+
+public class Perspective implements IPerspective {
+    private final String name;
+    protected byte[] byteArray;
+
+    public Perspective(String name) {
+        this.name = name;
+        byteArray = new byte[0];
+    }
+
+    @Override
+    public byte[] getByteArray() {
+        return byteArray;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setByteArray(byte[] byteArray) {
+        this.byteArray = byteArray;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+}
\ No newline at end of file
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/PerspectiveFactory.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/PerspectiveFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..d636d6e301f8d847b403f870dc515dd6e6174720
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/PerspectiveFactory.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.perspective;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import javax.swing.Action;
+
+import fr.soleil.docking.action.NewPerspectiveAction;
+import fr.soleil.docking.action.RemovePerspectiveAction;
+import fr.soleil.docking.action.SelectPerspectiveAction;
+import fr.soleil.docking.exception.DockingException;
+import fr.soleil.lib.project.ObjectUtils;
+
+public class PerspectiveFactory implements IPerspectiveFactory {
+
+    private static final String DEFAULT_PERSPECTIVE_NAME = "Default";
+
+    protected PropertyChangeSupport support;
+    private final List<IPerspective> perspectives;
+    private IPerspective selectedPerspective;
+    private final String defaultPerspectiveName;
+
+    public PerspectiveFactory() {
+        this(new Perspective(DEFAULT_PERSPECTIVE_NAME));
+    }
+
+    public PerspectiveFactory(IPerspective defaultt) {
+        perspectives = new ArrayList<IPerspective>(1);
+        defaultPerspectiveName = defaultt.getName();
+        perspectives.add(defaultt);
+        selectedPerspective = defaultt;
+        support = new PropertyChangeSupport(this);
+    }
+
+    @Override
+    public IPerspective createPerspective(final String name) {
+        IPerspective result = this.getPerspective(name);
+        if (result == null) {
+            result = new Perspective(name);
+            this.add(result);
+        }
+
+        return result;
+    }
+
+    /**
+     * @param e
+     * @return
+     * @see java.util.ArrayList#add(java.lang.Object)
+     */
+    public boolean add(IPerspective e) {
+        boolean result = perspectives.add(e);
+        if (result) {
+            support.fireIndexedPropertyChange(PERSPECTIVES, perspectives.indexOf(e), null, result);
+        }
+
+        return result;
+    }
+
+    @Override
+    public IPerspective getPerspective(Object id) {
+        IPerspective result = null;
+        if (id instanceof String) {
+            String name = (String) id;
+            for (IPerspective perspective : perspectives) {
+                if (name.equalsIgnoreCase(perspective.getName())) {
+                    result = perspective;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public IPerspective getSelectedPerspective() {
+        return selectedPerspective;
+    }
+
+    @Override
+    public void setSelectedPerspective(IPerspective selectedPerspective) {
+        if ((selectedPerspective != null) && (!selectedPerspective.equals(this.selectedPerspective))
+                && perspectives.contains(selectedPerspective)) {
+            IPerspective old = this.selectedPerspective;
+            this.selectedPerspective = selectedPerspective;
+            support.firePropertyChange(SELECTED_PERSPECTIVE, old, this.selectedPerspective);
+        }
+    }
+
+    @Override
+    public void setSelectedPerspective(String perspective) {
+        setSelectedPerspective(getPerspective(perspective));
+    }
+
+    @Override
+    public void loadPreferences(Preferences prefs) {
+        Preferences factoryPrefs = prefs.node("PerspectiveFactory");
+        Preferences perspectivesPrefs = factoryPrefs.node("Perspectives");
+
+        String[] keys = new String[0];
+        try {
+            keys = perspectivesPrefs.keys();
+        } catch (BackingStoreException e1) {
+            e1.printStackTrace();
+        }
+
+        byte[] ko = new byte[0];
+        byte[] layout = null;
+        IPerspective perspective = null;
+        for (int i = 0; i < keys.length; i++) {
+            perspective = this.getPerspective(keys[i]);
+            if (perspective == null) {
+                perspective = this.createPerspective(keys[i]);
+            }
+            layout = perspectivesPrefs.getByteArray(keys[i], ko);
+            if (layout != ko) {
+                perspective.setByteArray(layout);
+            }
+        }
+
+        // get the value of
+        String selected = factoryPrefs.get("selected", selectedPerspective.getName());
+        this.setSelectedPerspective(this.getPerspective(selected));
+
+    }
+
+    @Override
+    public void savePreferences(Preferences prefs) {
+        Preferences factoryPrefs = prefs.node("PerspectiveFactory");
+        Preferences perspectivesPrefs = factoryPrefs.node("Perspectives");
+
+        try {
+            factoryPrefs.clear();
+            perspectivesPrefs.clear();
+        } catch (BackingStoreException e1) {
+            e1.printStackTrace();
+        }
+        factoryPrefs.put("selected", selectedPerspective.getName());
+        for (IPerspective perspective : perspectives) {
+
+            perspectivesPrefs.putByteArray(perspective.getName(), perspective.getByteArray());
+        }
+    }
+
+    @Override
+    public List<Action> getActionList() {
+        List<Action> result = new ArrayList<Action>(1);
+
+        for (IPerspective perspective : perspectives) {
+            result.add(new SelectPerspectiveAction(this, perspective));
+        }
+
+        result.add(new NewPerspectiveAction(this));
+        result.add(new RemovePerspectiveAction(this));
+
+        return result;
+    }
+
+    @Override
+    public void saveSelected(File file) throws DockingException {
+        savePerspective(file, selectedPerspective);
+    }
+
+    @Override
+    public void savePerspective(File file, IPerspective perspective) throws DockingException {
+        if ((file != null) && (perspective != null)) {
+            DockingException dockingException = null;
+            FileOutputStream out = null;
+            try {
+                out = new FileOutputStream(file);
+                try {
+                    out.write(perspective.getByteArray());
+                } catch (Exception e) {
+                    if (dockingException == null) {
+                        dockingException = new DockingException("Error during file writing", e);
+                    }
+                } finally {
+                    try {
+                        out.close();
+                    } catch (Exception e) {
+                        if (dockingException == null) {
+                            dockingException = new DockingException("Error while releasing file access", e);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                if (dockingException == null) {
+                    dockingException = new DockingException("Error during file access", e);
+                }
+            }
+            if (dockingException != null) {
+                throw dockingException;
+            }
+        }
+    }
+
+    /**
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)
+     */
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        support.addPropertyChangeListener(listener);
+    }
+
+    /**
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)
+     */
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        support.removePropertyChangeListener(listener);
+    }
+
+    @Override
+    public IPerspective getDefault() {
+
+        return this.getPerspective(defaultPerspectiveName);
+    }
+
+    @Override
+    public IPerspective[] getPerspectives() {
+        return perspectives.toArray(new IPerspective[perspectives.size()]);
+    }
+
+    @Override
+    public IPerspective removePerspective(final IPerspective p) {
+        int index;
+        if (p == null) {
+            index = -1;
+        } else {
+            index = perspectives.indexOf(p);
+        }
+        if ((index > -1) && (!ObjectUtils.sameObject(p.getName(), defaultPerspectiveName))) {
+            // Exist and it's not the default perspective
+            perspectives.remove(index);
+            support.fireIndexedPropertyChange(PERSPECTIVES, index, p, null);
+        }
+        return p;
+    }
+
+    public IPerspective removePerspective(final String name) {
+        return this.removePerspective(this.getPerspective(name));
+    }
+
+    /**
+     * Reads a <code>byte</code> array from an {@link InputStream} and returns it
+     * 
+     * @param in The {@link InputStream}
+     * @return A <code>byte[]</code>
+     * @throws IOException If a problem occurred while trying to read the {@link InputStream}
+     */
+    protected static byte[] readByteArray(InputStream in) throws IOException {
+        byte[] result = null;
+        if (in != null) {
+            result = new byte[in.available()];
+            int length = in.read(result);
+            if (length != result.length) {
+                result = null;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public IPerspective loadPerspectiveFromFile(File perspectiveFile, String perpectiveName) throws DockingException {
+        Perspective perspective;
+        if (perpectiveName == null) {
+            perspective = null;
+        } else {
+            perspective = new Perspective(perpectiveName);
+        }
+        loadFileInPerspective(perspectiveFile, perspective);
+        return perspective;
+    }
+
+    @Override
+    public void loadFileInPerspective(File perspectiveFile, IPerspective perspective) throws DockingException {
+        if ((perspectiveFile != null) && perspectiveFile.isFile() && (perspective != null)) {
+            try {
+                perspective.setByteArray(readByteArray(new FileInputStream(perspectiveFile)));
+            } catch (Exception e) {
+                throw new DockingException("Error during file reading", e);
+            }
+        }
+    }
+
+    @Override
+    public IPerspective loadPerspectiveFromResource(String resource, String perpectiveName) throws DockingException {
+        Perspective perspective;
+        if (perpectiveName == null) {
+            perspective = null;
+        } else {
+            perspective = new Perspective(perpectiveName);
+        }
+        loadResourceInPerspective(resource, perspective);
+        return perspective;
+    }
+
+    @Override
+    public void loadResourceInPerspective(String resource, IPerspective perspective) throws DockingException {
+        if ((resource != null) && (!resource.trim().isEmpty()) && (perspective != null)) {
+            try {
+                perspective.setByteArray(readByteArray(getClass().getResourceAsStream(resource)));
+            } catch (Exception e) {
+                throw new DockingException("Error during resource reading", e);
+            }
+        }
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/perspective/ResourcePerspective.java b/dockingcore/src/main/java/fr/soleil/docking/perspective/ResourcePerspective.java
new file mode 100644
index 0000000000000000000000000000000000000000..eecd8f11c5010f0fda5bc29e19ab0749a362b8e0
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/perspective/ResourcePerspective.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.perspective;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+@Deprecated
+public class ResourcePerspective extends Perspective {
+
+    public ResourcePerspective(String name, String resource) throws IOException {
+        super(name);
+        InputStream in = ResourcePerspective.this.getClass().getResourceAsStream(resource);
+        if (in != null) {
+            byteArray = PerspectiveFactory.readByteArray(in);
+        }
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/util/DockingUtils.java b/dockingcore/src/main/java/fr/soleil/docking/util/DockingUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed4a2454e96d44a06a1b79c850c47cc02b8dd672
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/util/DockingUtils.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.util;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import fr.soleil.docking.view.IView;
+
+/**
+ * A class that gives some common useful methods about docking
+ * 
+ * @author girardot
+ */
+public class DockingUtils {
+
+    /**
+     * Generates an {@link AbstractAction} that can be used to display a given {@link IView}
+     * 
+     * @param view The concerned {@link IView}
+     * @return An {@link AbstractAction}
+     */
+    public static AbstractAction generateShowViewAction(final IView view) {
+        AbstractAction action = new AbstractAction(view.getTitle()) {
+
+            private static final long serialVersionUID = 1387050898689913657L;
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                view.setVisible(true);
+                view.select();
+            }
+        };
+        action.putValue(AbstractAction.SMALL_ICON, view.getIcon());
+        return action;
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/view/AbstractViewFactory.java b/dockingcore/src/main/java/fr/soleil/docking/view/AbstractViewFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce0611d4a9036d0ce094d3fc1b0078506d85071d
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/view/AbstractViewFactory.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.view;
+
+import java.awt.Component;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.prefs.Preferences;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+
+import fr.soleil.docking.action.ViewAction;
+
+/**
+ * Basic implementation of {@link IViewFactory}
+ * 
+ * @author girardot
+ */
+public abstract class AbstractViewFactory implements IViewFactory {
+
+    protected final Map<Object, IView> views;
+    protected final PropertyChangeSupport support;
+
+    public AbstractViewFactory() {
+        super();
+        views = new ConcurrentHashMap<Object, IView>();
+        support = new PropertyChangeSupport(this);
+    }
+
+    @Override
+    public IView getView(Object id) {
+        IView result = null;
+        if (id != null) {
+            result = views.get(id);
+        }
+        return result;
+    }
+
+    public Component getViewComponent(Object id) {
+        Component component;
+        IView view = getView(id);
+        if (view == null) {
+            component = null;
+        } else {
+            component = view.getComponent();
+        }
+        return component;
+    }
+
+    protected void setViewEnabled(Object id, boolean enabled) {
+        IView view = getView(id);
+        if (view != null) {
+            view.setVisible(enabled);
+            view.setEnabled(enabled);
+        }
+    }
+
+    @Override
+    public void loadPreferences(Preferences prefs) {
+        // Does nothing in particular. If you expect something to be done, you should extend this class and override
+        // this method
+    }
+
+    @Override
+    public void savePreferences(Preferences prefs) {
+        // Does nothing in particular. If you expect something to be done, you should extend this class and override
+        // this method
+    }
+
+    protected IView addView(IView view, boolean warnSupport) {
+        IView added = null;
+        if (view != null) {
+            Object id = view.getId();
+            if (id != null) {
+                if (!views.containsKey(id)) {
+                    views.put(id, view);
+                    if (views.get(id) == view) {
+                        added = view;
+                    }
+                }
+            }
+        }
+        if (warnSupport && (added != null)) {
+            synchronized (support) {
+                support.firePropertyChange(VIEWS, null, view);
+            }
+        }
+        return added;
+    }
+
+    @Override
+    public IView addView(IView view) {
+        return addView(view, true);
+    }
+
+    @Override
+    public IView removeView(Object id) {
+        IView toRemove;
+        if (id == null) {
+            toRemove = null;
+        } else {
+            toRemove = views.remove(id);
+            if (toRemove != null) {
+                synchronized (support) {
+                    support.firePropertyChange(VIEWS, toRemove, null);
+                }
+            }
+        }
+        return toRemove;
+    }
+
+    @Override
+    public IView addView(String title, Icon icon, Component component, Object id, JComponent dockingArea) {
+        IView view = createView(title, icon, component, id);
+        updateViewForDockingArea(view, dockingArea);
+        return addView(view, dockingArea == null);
+    }
+
+    protected abstract IView createView(String title, Icon icon, Component component, Object id);
+
+    protected abstract void updateViewForDockingArea(IView view, JComponent dockingArea);
+
+    @Override
+    public boolean removeView(IView view) {
+        boolean result;
+        if (view == null) {
+            result = false;
+        } else {
+            Object id = view.getId();
+            IView temp = getView(id);
+            if (temp == view) {
+                result = true;
+                removeView(id);
+            } else {
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public List<Action> getActionList() {
+        List<Action> result = new ArrayList<Action>(views.size());
+        for (IView view : views.values()) {
+            if (view != null) {
+                result.add(new ViewAction(view));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public int size() {
+        return views.size();
+    }
+
+    @Override
+    public Collection<IView> getViews() {
+        return views.values();
+    }
+
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        support.addPropertyChangeListener(listener);
+    }
+
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        support.removePropertyChangeListener(listener);
+    }
+
+    @Override
+    public Object readViewId(ObjectInputStream in) throws IOException {
+        Object id = null;
+        try {
+            id = in.readObject();
+        } catch (ClassNotFoundException e) {
+            throw new IOException(e);
+        }
+        return id;
+    }
+
+    @Override
+    public void writeViewId(Object id, ObjectOutputStream out) throws IOException {
+        out.writeObject(id);
+    }
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/view/IView.java b/dockingcore/src/main/java/fr/soleil/docking/view/IView.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c8d85aef40446c3b9dd728b0f4967f8449b71bd
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/view/IView.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.view;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.Icon;
+
+import fr.soleil.docking.listener.IViewListener;
+
+/**
+ * A dynamically created view containing an id.
+ * 
+ * @author Hardion
+ * @author GIRARDOT
+ */
+public interface IView {
+
+    /**
+     * Returns the view id.
+     * 
+     * @return the view id
+     */
+    public Object getId();
+
+    /**
+     * @return the enabled
+     */
+    public boolean isEnabled();
+
+    /**
+     * @param enabled the enabled to set
+     */
+    public void setEnabled(boolean enabled);
+
+    /**
+     * @return the enabled
+     */
+    public boolean isVisible();
+
+    /**
+     * @param enabled the enabled to set
+     */
+    public void setVisible(boolean visible);
+
+    /**
+     * Forces this {@link IView} to be selected
+     */
+    public void select();
+
+    /**
+     * @return the title
+     */
+    public String getTitle();
+
+    /**
+     * Sets this {@link IView}'s title
+     * 
+     * @param title The title to set
+     */
+    public void setTitle(String title);
+
+    /**
+     * @return the icon
+     */
+    public Icon getIcon();
+
+    /**
+     * Sets this {@link IView}'s icon
+     * 
+     * @param icon The icon to set
+     */
+    public void setIcon(Icon icon);
+
+    /**
+     * @return the component
+     */
+    public Component getComponent();
+
+    /**
+     * Returns this {@link IView}'s background {@link Color}
+     * 
+     * @return A {@link Color}
+     */
+    public Color getViewBackground();
+
+    /**
+     * Sets the background {@link Color} of this {@link IView}
+     * 
+     * @param bg The background {@link Color} to set
+     */
+    public void setViewBackground(Color bg);
+
+    /**
+     * Returns this {@link IView}'s foreground {@link Color}
+     * 
+     * @return A {@link Color}
+     */
+    public Color getViewForeground();
+
+    /**
+     * Sets the foreground {@link Color} of this {@link IView}
+     * 
+     * @param fg The foreground {@link Color} to set
+     */
+    public void setViewForeground(Color fg);
+
+    /**
+     * Sets the {@link IView} closable or not.
+     * 
+     * @param closable The boolean to set.
+     */
+    public void setClosable(boolean closable);
+
+    /**
+     * Add an {@link IViewListener} to the view..
+     * 
+     * @param listener The {@link IViewListener} to add.
+     */
+    public void addViewListener(IViewListener listener);
+
+    /**
+     * Removes an {@link IViewListener} from the view..
+     * 
+     * @param listener The {@link IViewListener} to remove.
+     */
+    public void removeViewListener(IViewListener listener);
+
+}
diff --git a/dockingcore/src/main/java/fr/soleil/docking/view/IViewFactory.java b/dockingcore/src/main/java/fr/soleil/docking/view/IViewFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a947981ad902cbd779f64ef0a7907f43066b9c
--- /dev/null
+++ b/dockingcore/src/main/java/fr/soleil/docking/view/IViewFactory.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2019 Synchrotron SOLEIL
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser Public License v2.1
+ * which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+ ******************************************************************************/
+package fr.soleil.docking.view;
+
+import java.awt.Component;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.prefs.Preferences;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+
+import fr.soleil.docking.ADockingManager;
+
+/**
+ * A factory that takes care of initializing dockable components and transmitting models.
+ * 
+ * @author Hardion
+ * @author GIRARDOT
+ */
+public interface IViewFactory {
+
+    public static final String VIEWS = "views";
+
+    /**
+     * Returns the DynamicView associated with this id (creates the
+     * DynamicView).
+     * 
+     * @param id
+     *            The id of the desired DynamicView
+     * @return The DynamicView associated with this id
+     */
+    public IView getView(Object id);
+
+    public Collection<IView> getViews();
+
+    /**
+     * Returns the ActionList
+     * 
+     * @param id
+     *            The id of the desired DynamicView
+     * @return The DynamicView associated with this id
+     */
+    public List<Action> getActionList();
+
+    /**
+     * Saves preferences
+     * 
+     * @param prefs preferences in which to save
+     */
+    public void savePreferences(Preferences prefs);
+
+    /**
+     * Loads preferences
+     * 
+     * @param prefs preferences to load
+     */
+    public void loadPreferences(Preferences prefs);
+
+    public int size();
+
+    /**
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)
+     */
+    public void addPropertyChangeListener(PropertyChangeListener listener);
+
+    /**
+     * @param listener
+     * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener);
+
+    public Object readViewId(ObjectInputStream in) throws IOException;
+
+    public void writeViewId(Object id, ObjectOutputStream out) throws IOException;
+
+    public IView addView(IView view);
+
+    /**
+     * Creates an {@link IView} for a given {@link Component}, adds it in the list of views, and
+     * tries to put it in a docking area
+     * 
+     * @param title The {@link IView} title
+     * @param icon The {@link IView} {@link Icon}
+     * @param component The concerned {@link Component}
+     * @param id The {@link IView} id
+     * @param dockingArea The docking area
+     * @return The {@link IView} if it was successfully created and added, <code>null</code> otherwise
+     */
+    public IView addView(String title, Icon icon, Component component, Object id, JComponent dockingArea);
+
+    public boolean removeView(IView view);
+
+    /**
+     * Removes an {@link IView}, determined by an id, from list and from the
+     * docking area.
+     * 
+     * @param id The id of the {@link IView} to remove.
+     * @return The removed {@link IView} if such an {@link IView} existed and
+     *         was successfully removed, <code>null</code> otherwise.
+     */
+    public IView removeView(Object id);
+
+    /**
+     * Creates a new {@link ADockingManager} based on this {@link IViewFactory}
+     * 
+     * @return An {@link ADockingManager}
+     */
+    public ADockingManager generateDockingManager();
+}