[commit] r1077 - in branches/ServiceReleases_for_10.8.18: . Doc GME GME/Core GME/Gme GME/Mga GME/PartBrowser Install Paradigms/MetaGME/MetaInterpreter Paradigms/MetaGME/MetaInterpreter/Rep Paradigms/UML/decorator SDK/DecoratorLib Tests/GPyUnit/GME-297 Tests/GPyUnit/GME-310

GMESRC Repository Notifications gme-commit at list.isis.vanderbilt.edu
Wed Nov 10 15:18:47 CST 2010


Author: volgy
Date: Wed Nov 10 15:18:47 2010
New Revision: 1077

Log:
Merging changes from the trunk and preparing release 10.11.10.

Added:
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/   (props changed)
      - copied from r1070, trunk/Tests/GPyUnit/GME-297/
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/   (props changed)
      - copied from r1070, trunk/Tests/GPyUnit/GME-310/
Replaced:
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/GME297ModelRefportTest.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/GME297ModelRefportTest.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/gme.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/gme.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/mgadiff.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/mgadiff.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test1-correct.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test1-correct.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test1.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test1.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test2-correct.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test2-correct.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test2.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test2.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test3-correct.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-297/test3-correct.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/GME310ModelRefportTest.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/GME310ModelRefportTest.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/gme.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/gme.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/mgadiff.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/mgadiff.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test.py
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/test.py
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test1-correct.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/test1-correct.mga
   branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test1.mga
      - copied unchanged from r1070, trunk/Tests/GPyUnit/GME-310/test1.mga
Modified:
   branches/ServiceReleases_for_10.8.18/   (props changed)
   branches/ServiceReleases_for_10.8.18/Doc/README_in.txt
   branches/ServiceReleases_for_10.8.18/GME/Core/CoreAttribute.cpp
   branches/ServiceReleases_for_10.8.18/GME/Gme/ChildFrm.h
   branches/ServiceReleases_for_10.8.18/GME/Gme/GMEVersion.h
   branches/ServiceReleases_for_10.8.18/GME/Mga/MgaComplexOps.cpp
   branches/ServiceReleases_for_10.8.18/GME/PartBrowser/PartBrowserPane.cpp
   branches/ServiceReleases_for_10.8.18/GME/regrelease.bat
   branches/ServiceReleases_for_10.8.18/Install/GME_dyn.wxi
   branches/ServiceReleases_for_10.8.18/Install/symbols.cmd
   branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/Rep/Dumper.cpp
   branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/StdAfx.cpp
   branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLClassPart.cpp
   branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.cpp
   branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.h
   branches/ServiceReleases_for_10.8.18/SDK/DecoratorLib/ClassLabelPart.cpp

Modified: branches/ServiceReleases_for_10.8.18/Doc/README_in.txt
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Doc/README_in.txt	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Doc/README_in.txt	Wed Nov 10 15:18:47 2010	(r1077)
@@ -30,8 +30,23 @@
 1. Release Notes
 ************************************************
 
+Release Notes of Release r10.11.10
+----------------------------------
+  - This is a service release for r10.8.18
+    Hence, it is binary compatible with that.
+  - Fixing GME-306: do not show each model separately 
+    in the Windows7 taskbar
+  - Fixing GME-304: do not allow ClassCopy stereotypes
+    to be edited with the UML Decorator
+  - Fixing GME-305: UML decorator visualization
+    glitch in set mode
+  - Fixing GME-210: copying folders with subfolder (MGA)
+  - Fixing GME-297 ang GME-311: crashes and other bugs in MGA 
+    while moving FCOs
+  - 
+  
 Release Notes of Release r10.10.10
----------------------------------
+----------------------------------
   - This is a service release for r10.8.18
     Hence, it is binary compatible with that.
   - Fixing ObjectInspector bug ("could not write..." error messages)

Modified: branches/ServiceReleases_for_10.8.18/GME/Core/CoreAttribute.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/Core/CoreAttribute.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/Core/CoreAttribute.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -1104,7 +1104,8 @@
 		ASSERT( IsValidIterator(collection, backref) );
 
 		collection.erase( backref );
-		backref = objects_iterator(); // was: backref = NULL;
+		// KMS: assigning a singular iterator is undefined. I saw a crash when registering MetaGME
+		// backref = objects_iterator(); // was: backref = NULL;
 		isEmpty = true;
 	}
 	else

Modified: branches/ServiceReleases_for_10.8.18/GME/Gme/ChildFrm.h
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/Gme/ChildFrm.h	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/Gme/ChildFrm.h	Wed Nov 10 15:18:47 2010	(r1077)
@@ -61,6 +61,7 @@
 	afx_msg void OnSize(UINT nType, int cx, int cy);
 	afx_msg void OnUpdateFrameTitle(BOOL bAddToTitle);
 	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	virtual void RegisterTaskbarTab(CMDIChildWndEx* pWndBefore = NULL) { } // disable each tab showing up on the taskbar in windows 7
 };
 
 /////////////////////////////////////////////////////////////////////////////

Modified: branches/ServiceReleases_for_10.8.18/GME/Gme/GMEVersion.h
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/Gme/GMEVersion.h	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/Gme/GMEVersion.h	Wed Nov 10 15:18:47 2010	(r1077)
@@ -2,7 +2,7 @@
 #define _GMEVERSION_H_
 
 #define GME_VERSION_MAJOR	10		// MAJOR = Last two digits of Year
-#define GME_VERSION_MINOR	10		// MINOR = Month
+#define GME_VERSION_MINOR	11		// MINOR = Month
 #define GME_VERSION_PLEVEL	10		// PATCH LEVEL = Day
 
 #define _VERSION_STRING2(x)	#x 

Modified: branches/ServiceReleases_for_10.8.18/GME/Mga/MgaComplexOps.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/Mga/MgaComplexOps.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/Mga/MgaComplexOps.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -591,9 +591,15 @@
 					children.Sort();
 				}
 				ITERATE_THROUGH(children) {
-					if(ObjTreeReconnect(ITER,crealist, derivtgt)) {
-						containedexternal = true;
-						if(n == DTID_CONNROLE) break; // stop processing rolesegments after an ext ref.
+					if (GetMetaID(ITER) == DTID_FOLDER) {
+						if(ObjTreeReconnectFoldersToo(ITER, crealist, derivtgt)) {
+							containedexternal = true;
+						}
+					} else {
+						if(ObjTreeReconnect(ITER, crealist, derivtgt)) {
+							containedexternal = true;
+							if(n == DTID_CONNROLE) break; // stop processing rolesegments after an ext ref.
+						}
 					}
 				}
 			}
@@ -762,35 +768,93 @@
 void ObjTreeCheckINTORelations(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals) {
 	metaid_type n = GetMetaID(self);
 	ASSERT(n >= DTID_MODEL && n <= DTID_SET);
-	CoreObjs xrefs = self[ATTRID_XREF + ATTRID_COLLECTION]; 
-	ITERATE_THROUGH(xrefs) {
-		metaid_type st = GetMetaID(ITER);
-		if(st == DTID_SETNODE || st == DTID_CONNROLE) {
+	if (n == DTID_REFERENCE) {
+		// GME-311: need to delete connections into refport 'conn_seg' iff 
+		//   connection 'rel_owner' is not in internals and 'conn_seg' is the actual connection end (not an intermediary)
+		CoreObjs conn_segs = self[ATTRID_SEGREF + ATTRID_COLLECTION];
+		ITERATE_THROUGH(conn_segs) {
+			metaid_type st = GetMetaID(ITER);
+			ASSERT(st == DTID_CONNROLESEG);
+			if (st != DTID_CONNROLESEG) {
+				continue;
+			}
+			CoreObj role = ITER[ATTRID_CONNSEG];
 			CoreObj rel_owner = ITER.GetMgaObj();
-			if (!rel_owner) {
-				continue;	// connection/set might be deleted due to a previous relation
+			if (!rel_owner || !role) {
+				continue;	// connection might be deleted due to a previous relation
 			}
-			if(internals.find(rel_owner) == internals.end()) {
-				int ttt = st == DTID_CONNROLE ? MM_CONN : MM_SET;
+			ASSERT(GetMetaID(role) == DTID_CONNROLE);
+			ASSERT(GetMetaID(rel_owner) == DTID_CONNECTION);
+			#ifdef _DEBUG
+			CComBSTR conn_name = rel_owner[ATTRID_NAME], role_name = role[ATTRID_NAME];
+			#endif
+			ASSERT(ObjForCore(rel_owner)->simpleconn()); // KMS: don't think we can get here without a simpleconn
+			if (internals.find(rel_owner) == internals.end() && ObjForCore(rel_owner)->simpleconn()) {
 				setcheck(mgaproject, rel_owner, CHK_CHANGED);
-				switch(MODEMASK(ttt, MM_INTO)) {
+				switch(MODEMASK(MM_CONN, MM_INTO)) {
 				case MM_ERROR: COMTHROW(E_MGA_OP_REFUSED);
 					break;
-				case MM_CLEAR: 
-					if( st == DTID_CONNROLE && ObjForCore(rel_owner)->simpleconn() ||
-					    MODEFLAG(ttt, MM_FULLDELETE)) {
-					    ObjForCore(rel_owner)->inDeleteObject();
-					} 
-					else {
-						CoreObjMark(self, st == DTID_CONNROLE ? OBJEVENT_DISCONNECTED : OBJEVENT_SETEXCLUDED);
-						CoreObjMark(rel_owner, OBJEVENT_RELATION);
-						SingleObjTreeDelete(ITER);
-					}
+				case MM_CLEAR:
+					CoreObjs refport_refs = role[ATTRID_CONNSEG+ATTRID_COLLECTION]; // i.e. refport containers
+					long count;
+					COMTHROW(refport_refs->get_Count(&count));
+					if (count == 0) {
+						// i.e. not a refport
+						ASSERT(FALSE);
+						continue;
+					}
+					CComPtr<ICoreObject> refport_ref;
+					COMTHROW(refport_refs->get_Item(1, &refport_ref));
+					CoreObj end_refport_ref(refport_ref.p);
+					// i.e. if (end_refport_ref == ITER)
+					if (GetMetaID(end_refport_ref) == GetMetaID(ITER) && end_refport_ref.GetObjID() == ITER.GetObjID())
+						ObjForCore(rel_owner)->inDeleteObject();
 					break;
 				}
-			}	
+			}
 		}
 	}
+
+	CoreObjs xrefs = self[ATTRID_XREF + ATTRID_COLLECTION]; 
+	ITERATE_THROUGH(xrefs) {
+		metaid_type st = GetMetaID(ITER);
+		if(st != DTID_SETNODE && st != DTID_CONNROLE) {
+			continue;
+		}
+		CoreObj rel_owner = ITER.GetMgaObj();
+		if (!rel_owner) {
+			continue;	// connection/set might be deleted due to a previous relation
+		}
+
+		if(internals.find(rel_owner) == internals.end()) {
+			int ttt = st == DTID_CONNROLE ? MM_CONN : MM_SET;
+			setcheck(mgaproject, rel_owner, CHK_CHANGED);
+			switch(MODEMASK(ttt, MM_INTO)) {
+			case MM_ERROR: COMTHROW(E_MGA_OP_REFUSED);
+				break;
+			case MM_CLEAR: 
+				if (st == DTID_CONNROLE && ObjForCore(rel_owner)->simpleconn()) {
+					// GME-297: don't delete connections connecting to refports
+					// (outside connections to inside refports are deleted above)
+					long count = 0;
+					CoreObjs refport_refs = ITER[ATTRID_CONNSEG+ATTRID_COLLECTION]; // i.e. refport containers
+					COMTHROW(refport_refs->get_Count(&count));
+					if (count == 0) {
+						// this connection role is connected directly; it is not connected to a refport
+						ObjForCore(rel_owner)->inDeleteObject();
+					}
+				} else if (MODEFLAG(ttt, MM_FULLDELETE)) {
+					ObjForCore(rel_owner)->inDeleteObject();
+				} 
+				else {
+					CoreObjMark(self, st == DTID_CONNROLE ? OBJEVENT_DISCONNECTED : OBJEVENT_SETEXCLUDED);
+					CoreObjMark(rel_owner, OBJEVENT_RELATION);
+					SingleObjTreeDelete(ITER);
+				}
+				break;
+			}
+		}	
+	}
 	{
 	CoreObjs refs = self[ATTRID_REFERENCE + ATTRID_COLLECTION]; 
 	ITERATE_THROUGH(refs) {
@@ -1356,7 +1420,7 @@
 					ASSERT(targettype == DTID_MODEL);
 					CComPtr<IMgaMetaRole> r;
 					if(rlist) COMTHROW(rlist->get_Item(i+1, &r));
-					if(!r) {   // NO metanaem given, inherit that of original object
+					if(!r) {   // NO metaname given, inherit that of original object
 						CComPtr<IMgaMetaFCO> mf; 
 						COMTHROW(get_Meta(&mf));
 						CComQIPtr<IMgaMetaModel> parentmeta = mf;

Modified: branches/ServiceReleases_for_10.8.18/GME/PartBrowser/PartBrowserPane.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/PartBrowser/PartBrowserPane.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/PartBrowser/PartBrowserPane.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -84,9 +84,9 @@
 		return NULL;
 
 	try {
-		std::vector<PartWithDecorator> pdtv = pdts[currentAspectIndex];
+		const std::vector<PartWithDecorator>& pdtv = pdts[currentAspectIndex];
 		// calculate the maximum size
-		for (std::vector<PartWithDecorator>::iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
+		for (std::vector<PartWithDecorator>::const_iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
 			ASSERT((*ii).decorator != NULL);
 			long x1 = 0; long y1 = 0;
 			long x2 = 0; long y2 = 0;
@@ -242,9 +242,9 @@
 	CPoint pt = CPoint(leftStartPos, topMargin);
 
 	try {
-		std::vector<PartWithDecorator> pdtv = pdts[currentAspectIndex];
+		const std::vector<PartWithDecorator>& pdtv = pdts[currentAspectIndex];
 		// calculate the maximum size
-		for (std::vector<PartWithDecorator>::iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
+		for (std::vector<PartWithDecorator>::const_iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
 			ASSERT((*ii).decorator != NULL);
 			long sizeX = 0;
 			long sizeY = 0;
@@ -255,8 +255,8 @@
 			if (objColumn == 0) {
 				rowHeight = size.cy;
 
-				std::vector<PartWithDecorator>::iterator iibak = ii;
-				for (std::vector<PartWithDecorator>::iterator jj = ++ii; jj != pdtv.end() && (objColumn + 1) < objNumInRow; ++jj) {
+				std::vector<PartWithDecorator>::const_iterator iibak = ii;
+				for (std::vector<PartWithDecorator>::const_iterator jj = ++ii; jj != pdtv.end() && (objColumn + 1) < objNumInRow; ++jj) {
 					ASSERT((*jj).decorator != NULL);
 					long sizeX2 = 0;
 					long sizeY2 = 0;
@@ -373,9 +373,9 @@
 	maxSize.cy = 10;
 
 	try {
-		std::vector<PartWithDecorator> pdtv = pdts[currentAspectIndex];
+		const std::vector<PartWithDecorator>& pdtv = pdts[currentAspectIndex];
 		// calculate the maximum size
-		for (std::vector<PartWithDecorator>::iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
+		for (std::vector<PartWithDecorator>::const_iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
 			ASSERT((*ii).part != NULL);
 			ASSERT((*ii).decorator != NULL);
 
@@ -440,8 +440,8 @@
 
 	if (pdts.size() > 0 && currentAspectIndex >= 0) {
 		try {
-			std::vector<PartWithDecorator> pdtv = pdts[currentAspectIndex];
-			for (std::vector<PartWithDecorator>::iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
+			const std::vector<PartWithDecorator>& pdtv = pdts[currentAspectIndex];
+			for (std::vector<PartWithDecorator>::const_iterator ii = pdtv.begin(); ii != pdtv.end(); ++ii) {
 				if ((*ii).newDecorator) {
 					COMTHROW((*ii).newDecorator->DrawEx(dc.m_hDC, (ULONGLONG)(&gdipGraphics)));
 				} else {

Modified: branches/ServiceReleases_for_10.8.18/GME/regrelease.bat
==============================================================================
--- branches/ServiceReleases_for_10.8.18/GME/regrelease.bat	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/GME/regrelease.bat	Wed Nov 10 15:18:47 2010	(r1077)
@@ -5,6 +5,8 @@
 REM	Please consult with Peter before editing this file
 REM 
 
+REM FIXME Do we need to regasm mgadotnetservices.dll?
+
 echo Core.dll:
 regsvr32 /s "Core\Release\Core.dll"
 if errorlevel 1 goto errorlabel

Modified: branches/ServiceReleases_for_10.8.18/Install/GME_dyn.wxi
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Install/GME_dyn.wxi	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Install/GME_dyn.wxi	Wed Nov 10 15:18:47 2010	(r1077)
@@ -1,6 +1,6 @@
 <!-- DO NOT EDIT THIS FILE. WILL BE REGENERATED BY THE BUILD SCRIPTS -->
 <Include>
-   <?define VERSIONSTR='10.10.11' ?>
+   <?define VERSIONSTR='10.11.10' ?>
    <?define GUIDSTRMETAGME='{9D3F9884-FE60-409C-8FC1-45789193989B}' ?>
    <?define GUIDSTRHFSM='{757682DE-E57F-4003-9A7E-8EE5C0368980}' ?>
    <?define GUIDSTRSF='{A47F17D5-E360-4395-8351-AE3A1A843468}' ?>

Modified: branches/ServiceReleases_for_10.8.18/Install/symbols.cmd
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Install/symbols.cmd	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Install/symbols.cmd	Wed Nov 10 15:18:47 2010	(r1077)
@@ -1,3 +1,3 @@
-set VERSION=10.8.18
+set VERSION=10.11.10
 set DBGTOOLS=C:\Program Files\Debugging Tools for Windows (x64)
 "%DBGTOOLS%\symstore.exe" add /f %GME_ROOT%/Install/GME-%VERSION%-symbols /s \\atlantis\project\GME\symbols /r /t GME /v %VERSION% /c "GME Release %VERSION% symbols added" /compress
\ No newline at end of file

Modified: branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/Rep/Dumper.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/Rep/Dumper.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/Rep/Dumper.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -1096,6 +1096,9 @@
 
 bool Dumper::checkAll()
 {
+	const MON::Object& meta = this->m_BON_Project_Root_Folder->getObjectMeta();
+	if (meta.project().displayedName() != "MetaGME")
+		global_vars.err << MSG_WARNING  << "Warning: file's paradigm '" << meta.project().displayedName() << "' is not MetaGME\n";
 	bool res0 = checkRootFolder();
 	bool res1 = checkAllFCOs();
 	bool res2 = checkOrphanAttributes();

Modified: branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/StdAfx.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/StdAfx.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Paradigms/MetaGME/MetaInterpreter/StdAfx.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -8,14 +8,4 @@
 
 #include <statreg.h>
 
-#if _ATL_VER < 0x0700
-#include <statreg.cpp>
-#endif // _ATL_VER < 0x0700
-
 #endif // _ATL_STATIC_REGISTRY
-
-#if _ATL_VER < 0x0700
-
-#include <atlimpl.cpp>
-
-#endif // _ATL_VER < 0x0700
\ No newline at end of file

Modified: branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLClassPart.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLClassPart.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLClassPart.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -53,7 +53,8 @@
 																	DecoratorSDK::COLOR_TRANSPARENT,
 																	DecoratorSDK::COLOR_GRAYED_OUT);
 				CComPtr<IMgaFCO> mgaFco = m_spFCO;
-				while(objtype == OBJTYPE_REFERENCE) {
+				bool is_reference = objtype == OBJTYPE_REFERENCE;
+				while (objtype == OBJTYPE_REFERENCE) {
 					CComPtr<IMgaReference> ref;
 					COMTHROW(mgaFco.QueryInterface(&ref));
 					mgaFco = NULL;
@@ -68,7 +69,7 @@
 					CString strStereotype;
 					if (DecoratorSDK::getFacilities().getAttribute(mgaFco ? mgaFco : m_spFCO, UML_STEREOTYPE_ATTR, strStereotype)) {
 						if (!strStereotype.IsEmpty()) {
-							m_StereotypePart = new UMLStereoLabelPart(this, m_eventSink, mgaFco ? mgaFco : m_spFCO);
+							m_StereotypePart = new UMLStereoLabelPart(this, m_eventSink, mgaFco ? mgaFco : m_spFCO, !is_reference);
 							m_StereotypePart->SetText(strStereotype);
 						}
 					}
@@ -80,7 +81,7 @@
 				CString strStereotype;
 				if (DecoratorSDK::getFacilities().getAttribute(m_spFCO, UML_STEREOTYPE_ATTR, strStereotype)) {
 					if (!strStereotype.IsEmpty()) {
-						m_StereotypePart = new UMLStereoLabelPart(this, m_eventSink, m_spFCO);
+						m_StereotypePart = new UMLStereoLabelPart(this, m_eventSink, m_spFCO, false);
 						m_StereotypePart->SetText(strStereotype);
 					}
 				}

Modified: branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -18,10 +18,11 @@
 //
 //################################################################################################
 
-UMLStereoLabelPart::UMLStereoLabelPart(PartBase* pPart, CComPtr<IMgaCommonDecoratorEvents> eventSink, CComPtr<IMgaFCO>& pFCO):
+UMLStereoLabelPart::UMLStereoLabelPart(PartBase* pPart, CComPtr<IMgaCommonDecoratorEvents> eventSink, CComPtr<IMgaFCO>& pFCO, bool bTextEditable):
 	DecoratorSDK::StereoLabelPart(pPart, eventSink),
 	m_spActualFCO(pFCO)
 {
+	m_bTextEditable = bTextEditable;
 }
 
 UMLStereoLabelPart::~UMLStereoLabelPart()

Modified: branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.h
==============================================================================
--- branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.h	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/Paradigms/UML/decorator/UMLStereoLabelPart.h	Wed Nov 10 15:18:47 2010	(r1077)
@@ -27,7 +27,7 @@
 	CComPtr<IMgaFCO>	m_spActualFCO;
 
 public:
-	UMLStereoLabelPart(PartBase* pPart, CComPtr<IMgaCommonDecoratorEvents> eventSink, CComPtr<IMgaFCO>& pFCO);
+	UMLStereoLabelPart(PartBase* pPart, CComPtr<IMgaCommonDecoratorEvents> eventSink, CComPtr<IMgaFCO>& pFCO, bool bTextEditable);
 	virtual ~UMLStereoLabelPart();
 
 	virtual void	ExecuteOperation			(const CString& newString);

Modified: branches/ServiceReleases_for_10.8.18/SDK/DecoratorLib/ClassLabelPart.cpp
==============================================================================
--- branches/ServiceReleases_for_10.8.18/SDK/DecoratorLib/ClassLabelPart.cpp	Wed Nov 10 13:10:13 2010	(r1076)
+++ branches/ServiceReleases_for_10.8.18/SDK/DecoratorLib/ClassLabelPart.cpp	Wed Nov 10 15:18:47 2010	(r1077)
@@ -46,7 +46,7 @@
 								   CRect(loc.left, loc.top + m_labelRelYPosition - size.cy,
 										 loc.right, loc.top + m_labelRelYPosition),
 								   pFont,
-								   (m_bActive) ? m_crText : COLOR_GRAYED_OUT,
+								   (m_bActive) ? m_crText : COLOR_GREY,
 								   TA_BOTTOM | TA_CENTER,
 								   m_iMaxTextLength,
 								   "",

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/GME297ModelRefportTest.mga (from r1070, trunk/Tests/GPyUnit/GME-297/GME297ModelRefportTest.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp (from r1070, trunk/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-297/GME297ModelRefportTest.xmp)
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!DOCTYPE paradigm SYSTEM "edf.dtd">
+
+<paradigm name="GME297ModelRefportTest" guid="{1164DAF2-157D-47D3-AA65-7CD12784CF82}" cdate="Thu Sep 23 11:45:28 2010" mdate="Thu Sep 23 11:45:28 2010" >
+
+	<comment></comment>
+
+	<author></author>
+
+	<folder name = "RootFolder" metaref = "1000"  subfolders = "KindFolder" >
+		<atom name = "KindAtom" metaref = "1001" >
+				<regnode name = "namePosition" value ="4"></regnode>
+		</atom>
+		<connection name = "KindConnection" metaref = "1002" >
+				<regnode name = "color" value ="0x000000"></regnode>
+				<regnode name = "dstStyle" value ="arrow"></regnode>
+				<regnode name = "srcStyle" value ="butt"></regnode>
+				<regnode name = "lineType" value ="solid"></regnode>
+			<connjoint>
+				<pointerspec name = "src">
+					<pointeritem desc = "KindAtom"></pointeritem>
+					<pointeritem desc = "KindModel KindAtom"></pointeritem>
+					<pointeritem desc = "KindModelReference KindAtom"></pointeritem>
+				</pointerspec>
+				<pointerspec name = "dst">
+					<pointeritem desc = "KindAtom"></pointeritem>
+					<pointeritem desc = "KindModel KindAtom"></pointeritem>
+					<pointeritem desc = "KindModelReference KindAtom"></pointeritem>
+				</pointerspec>
+			</connjoint>
+		</connection>
+		<reference name = "KindModelReference" metaref = "1003">
+				<regnode name = "namePosition" value ="4"></regnode>
+			<pointerspec name = "ref">
+				<pointeritem desc = "KindModel"></pointeritem>
+				<pointeritem desc = "KindModelReference"></pointeritem>
+			</pointerspec>
+		</reference>
+		<model name = "KindModel" metaref = "1004" >
+				<regnode name = "namePosition" value ="4"></regnode>
+				<regnode name = "isTypeInfoShown" value ="true"></regnode>
+			<role name = "KindAtom" metaref = "1005" kind = "KindAtom"></role>
+			<role name = "KindConnection" metaref = "1013" kind = "KindConnection"></role>
+			<role name = "KindModel" metaref = "1011" kind = "KindModel"></role>
+			<role name = "KindModelReference" metaref = "1006" kind = "KindModelReference"></role>
+			<aspect name = "KindAspect" metaref = "1007" >
+				<part metaref = "1008" role = "KindAtom" primary = "yes" linked = "yes"></part>
+				<part metaref = "1014" role = "KindConnection" primary = "yes" linked = "no"></part>
+				<part metaref = "1012" role = "KindModel" primary = "yes" linked = "no"></part>
+				<part metaref = "1009" role = "KindModelReference" primary = "yes" kindaspect = "KindAspect" linked = "no"></part>
+			</aspect>
+		</model>
+		<folder name = "KindFolder" metaref = "1010"  subfolders = "KindFolder" rootobjects = "KindModel" >
+		</folder>
+	</folder>
+</paradigm>

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/gme.py (from r1070, trunk/Tests/GPyUnit/GME-297/gme.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/gme.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-297/gme.py)
@@ -0,0 +1,605 @@
+#!/bin/python
+
+import re
+import sys
+import os.path
+import pythoncom
+import win32com.client
+import StringIO
+# For py2exe support
+# To generate the exe, be sure to rename or delete .../Python/lib/site-packages/win32com/gen_py
+# See http://www.py2exe.org/index.cgi/UsingEnsureDispatch
+if win32com.client.gencache.is_readonly == True:
+	#allow gencache to create the cached wrapper objects
+	win32com.client.gencache.is_readonly = False
+	# under p2exe the call in gencache to __init__() does not happen
+	# so we use Rebuild() to force the creation of the gen_py folder
+	try:
+		saveout = sys.stdout
+		try:
+			sys.stdout = output = StringIO.StringIO()
+			win32com.client.gencache.Rebuild()
+		finally:
+			sys.stdout = saveout
+	except:
+		print output.getvalue()
+		raise
+
+import pywintypes
+import subprocess
+import itertools
+
+# Elevation helpers
+def execute_elevated(*args):
+	# FIXME: support **kwargs
+	from win32com.shell.shell import ShellExecuteEx
+	from win32com.shell import shellcon
+	import win32process, win32event
+	import winxpgui
+	import win32api
+	import win32con
+	try:
+		hwnd = winxpgui.GetConsoleWindow()
+	except winxpgui.error:
+		hwnd = 0
+	parameters = ""
+	if not hasattr(sys, "frozen"):
+		# Not running under py2exe exe
+		parameters += "\"" + sys.argv[0] + "\" "
+	parameters += " ".join(map(lambda x: "\"" + str(x) + "\"", args))
+	print "Executing elevated with parameters " + parameters
+	# TODO: capture output (maybe via named pipe)
+	rc = ShellExecuteEx(hwnd=hwnd, fMask=shellcon.SEE_MASK_NOCLOSEPROCESS, lpVerb="runas", lpFile=sys.executable, 
+		lpParameters=parameters, nShow=win32con.SW_SHOW)
+	hproc = rc['hProcess']
+	win32event.WaitForSingleObject(hproc, win32event.INFINITE)
+	exit_code = win32process.GetExitCodeProcess(hproc)
+	if exit_code:
+		raise Exception("Error: subprocess failed (exit code %s)." % exit_code)
+
+def is_elevated():
+	import win32security
+	import win32api
+	hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_QUERY)
+	return win32security.GetTokenInformation(hToken, win32security.TokenElevation) != 0
+
+
+def maybe_elevate():
+	def decorator(func):
+		if sys.getwindowsversion()[0] < 6:
+			wrap = func
+		else:
+			def wrap(*args, **kwargs):
+				if not is_elevated():
+					execute_elevated(func.__name__, *args, **kwargs)
+				else:
+					func(*args, **kwargs)
+		setattr(sys.modules[__name__], func.__name__, wrap)
+		return wrap
+	return decorator
+
+ at maybe_elevate()
+def elevated_check_call(*args):
+	return subprocess.check_call(args)
+
+# GME functions
+def create_project(project, connection, paradigm):
+		try:
+			return project.Create(connection, paradigm)
+		except pywintypes.com_error as err:
+# from Mga.idl:
+#[helpstring("The paradigm is not registered")]
+#		E_MGA_PARADIGM_NOTREG			= 0x87650011,
+			if err.excepinfo and err.excepinfo[5] == -2023423983:
+				raise Exception("Paradigm '%s' not registered; can't open file '%s'" % (paradigm, connection), err)
+			raise err
+
+# aka CreateMga.vbs
+def xme2mga(xmefile, mgafile=None):
+	if not mgafile:
+		mgafile = os.path.splitext(xmefile)[0] + ".mga"
+	with Project.open(xmefile, mgafile) as project:
+		project.save(project.mgafile)
+		return project.mgafile
+
+def run_interpreter(interpreter, file, focusobj=None, selectedobj=None, param=0, mga_to_save=None):
+	with Project.open(file, mga_to_save=mga_to_save) as project:
+		project.run_interpreter(interpreter, focusobj, selectedobj, param)
+
+# MGAUTILLib.regaccessmode_enum.REGACCESS_BOTH = 3
+def get_paradigm_file(paradigm, regaccess=3):
+	"Returns the .mta file for a given registered paradigm"
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	guid = registrar.ParadigmGUIDString(regaccess, paradigm)
+	import uuid
+	buf = buffer(uuid.UUID(guid).bytes_le, 0, 16)
+	(connstr, guid) = registrar.QueryParadigm(paradigm, None, buf, regaccess)
+	# >>> constr
+	# "MGA=....mta"
+	return connstr[4:]
+
+
+def _associate(progid, paradigm, regaccess):
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	registrar.Associate(progid, paradigm, regaccess)
+
+ at maybe_elevate()
+def _associate_elevated(*args):
+	_associate(*args)
+
+def associate(progid, paradigm, regaccess=1):
+	"Associate a component with a paradigm"
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_associate_elevated(progid, paradigm, regaccess)
+	else:
+		_associate(progid, paradigm, regaccess)
+
+
+def is_registered(paradigm):
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	paradigms = []
+	# REGACCESS_USER = 1
+	paradigms.extend(registrar.Paradigms(1))
+	# REGACCESS_SYSTEM = 2
+	paradigms.extend(registrar.Paradigms(2))
+	return filter(lambda p: p == paradigm, paradigms)
+
+REGISTER = 128
+DONT_REGISTER = 0
+def register_if_not_registered(file):
+	"Register an xme or mga if it has not already been registered"
+	if os.path.splitext(file)[1] == ".xmp":
+		if not is_registered(os.path.splitext(file)[0]):
+			regxmp(file)
+		return
+	
+	# if we don't give GME an absolute path, it registers the mta with a relative path (which is bad)
+	with Project.open(os.path.abspath(file), mga_to_save=True) as project:
+		paradigm = project.project.RootFolder.Name
+		if not is_registered(paradigm):
+			project.run_interpreter("MGA.Interpreter.MetaInterpreter", param=REGISTER)
+			print "Paradigm '%s' is now registered" % paradigm
+		elif not os.path.isfile(get_paradigm_file(paradigm)):
+			#FIXME: should we look for the .xmp?
+			project.run_interpreter("MGA.Interpreter.MetaInterpreter", param=REGISTER)
+			print "Paradigm '%s' had nonexistant .mta; it is now reregistered" % paradigm
+		# TODO: can we check if it is up-to-date?
+		# or os.path.getmtime(get_paradigm_file(paradigm)) < os.path.getmtime(file):
+		else:
+			print "Paradigm '%s' is already registered" % paradigm
+
+def mga2xmp(mgafile, register=REGISTER):
+	# if we don't give GME an absolute path, it registers the mta with a relative path (which is bad)
+	run_interpreter("MGA.Interpreter.MetaInterpreter", os.path.abspath(mgafile), param=register, mga_to_save=True)
+
+def xme2xmp(xmefile, register=REGISTER):
+	mgafile = xme2mga(xmefile)
+	mga2xmp(mgafile, register)
+	return mgafile
+
+def _regxmp(xmpfile, regaccess):
+	REG_USER = 1
+	REG_SYSTEM = 2
+	REG_BOTH = 3
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	registrar.RegisterParadigmFromData("XML=" + os.path.abspath(xmpfile), "", regaccess)
+
+ at maybe_elevate()
+def _regxmp_elevated(xmpfile, regaccess):
+	_regxmp(xmpfile, regaccess)
+
+def regxmp(xmpfile, regaccess=1):
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_regxmp_elevated(xmpfile, regaccess)
+	else:
+		_regxmp(xmpfile, regaccess)
+
+def _reggmexmps(regaccess):
+	regaccess = int(regaccess)
+	for file in [ 'HFSM/HFSM.xmp', 'MetaGME/Paradigm/MetaGME.xmp', 'SF/SF.xmp', 'UML/UML.xmp' ]:
+		regxmp(os.path.join(os.path.join(os.environ['GME_ROOT'], 'Paradigms'), file), regaccess)
+
+ at maybe_elevate()
+def _reggmexmps_elevated(regaccess):
+	_reggmexmps(regaccess)
+
+def reggmexmps(regaccess=1):
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_reggmexmps_elevated(regaccess)
+	else:
+		_reggmexmps(regaccess)
+
+def mga2xme(mgafile, xmefile=None):
+	if not xmefile:
+		xmefile = os.path.splitext(mgafile)[0] + ".xme"
+
+	with Project.open(mgafile) as project:
+		project.save(xmefile)
+	return xmefile
+
+def register_component(file, warn_on_tlb_error=None):
+# TODO: on Vista or 7 we need to start an elevated registrar
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	# REGACCESS_BOTH	= 3,
+	try:
+		registrar.RegisterComponentLibrary(file, 3)
+	except pywintypes.com_error as err:
+# KMS: GME assumes that the .dll has a type library. If it is a CLR component, it will not.
+# Warn if the type library registration fails
+# #define TYPE_E_CANTLOADLIBRARY _HRESULT_TYPEDEF_(0x80029C4AL)
+		if warn_on_tlb_error and err.excepinfo and (err.excepinfo[5] & 0xffffffff == 0x80029c4a):
+			sys.stderr.write("Type library registration for %s failed" % file);
+		else:
+			raise err
+
+
+# UDM functions
+def meta2uml(mgafile, umlfile=None):
+	if not os.path.isfile(mgafile):
+		raise Exception("'" + mgafile + "' not found")
+	
+	if not umlfile:
+		umlfile = os.path.splitext(mgafile)[0] + "_uml.mga"
+	subprocess.check_call(["MetaGME2UML.exe", mgafile, umlfile])
+
+# aka CreateUdmXml.vbs
+def mga2udmxml(mgafile):
+	run_interpreter("MGA.Interpreter.UML2XML", mgafile, None, None, 128)
+
+# GReAT functions
+def RunGreatMasterInt(file):
+	file = os.path.abspath(file)
+	with Project.open(file) as project:
+		project.run_interpreter("MGA.Interpreter.GReAT Master Interpreter", param=128)
+# touch(1) the generated .udm file so incremental build works
+		configurations = (cast(fco) for fco in project.project.RootFolder.children() if fco.kind() == "Configurations").next()
+		configuration = (cast(fco) for fco in configurations.children() if fco.kind() == "Configuration").next()
+		metainformation = (cast(fco) for fco in configuration.children() if fco.kind() == "MetaInformation").next()
+		udmfile = os.path.dirname(file) + "/" + metainformation.AttributeByName("UdmProjectFile")
+		mtime = os.stat(udmfile).st_mtime
+	os.utime(file, (mtime, mtime))
+
+# Explorer context menu
+def context_menu_reg():
+	"""Register explorer context menu options"""
+	import _winreg
+	if hasattr(sys, "frozen"):
+		# Running under py2exe exe
+		gmepydir = os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding( )))
+	else:
+		gmepydir = os.path.dirname(__file__)
+	# Windows won't let us start gme.py from the context menu, so use the exe
+	gmepy = gmepydir + "\\gmepy.exe"
+
+	mga = "mga"
+	xme = "xme"
+	xmp = "xmp"
+	menus = [ (mga, "mga2xme"),
+			(mga, "mga2xmp"),
+			(mga, "mga2udmxml"),
+			(xme, "xme2mga"),
+			(xmp, "regxmp"),
+			]
+	regname = gmepydir + "\\gmepy_context_menu.reg"
+	with open(regname, "w") as reg:
+		reg.write("Windows Registry Editor Version 5.00\n")
+		for p in menus:
+			try:
+				key = _winreg.OpenKey(_winreg.ConnectRegistry(None, _winreg.HKEY_CLASSES_ROOT), "."+p[0])
+				n,v,t = _winreg.EnumValue(key, 0)
+				ext = v
+				_winreg.CloseKey(key)
+			except WindowsError:
+				ext = "."+p[0]
+			str = """[HKEY_CLASSES_ROOT\{ext}\shell]
+
+[HKEY_CLASSES_ROOT\{ext}\shell\{name}]
+
+[HKEY_CLASSES_ROOT\{ext}\shell\{name}\command]
+@="\\"{gmepy}\\" {name} \\\"%1\\\""
+
+""".format(ext=ext, name=p[1], gmepy=gmepy.replace("\\", "\\\\"))
+			reg.write(str)
+	elevated_check_call("regedit", regname)
+
+
+# GME Project functions
+import win32com.client.gencache
+# Generate .py's for GME Type Library
+# n.b. we don't use EnsureModule here because we don't properly version the typelib
+#   A change in the typelib may invalidate the cache, but gencache doesn't know it, e.g. GMESRC r947
+meta_module = win32com.client.gencache.MakeModuleForTypelib('{0ADEEC71-D83A-11D3-B36B-005004D38590}', 0, 1, 0)
+mga_module = win32com.client.gencache.MakeModuleForTypelib('{270B4F86-B17C-11D3-9AD1-00AA00B6FE26}', 0, 1, 0)
+
+gme_constants = getattr(meta_module, "constants")
+
+OBJTYPE_INTERFACE_MAP = {
+	gme_constants.OBJTYPE_MODEL: "IMgaModel",
+	# Seems IMgaAtom isn't generated because it defines no new methods
+#	2: "IMgaAtom",
+	gme_constants.OBJTYPE_ATOM: "IMgaFCO",
+	gme_constants.OBJTYPE_REFERENCE: "IMgaReference",
+	gme_constants.OBJTYPE_CONNECTION: "IMgaConnection",
+	gme_constants.OBJTYPE_SET: "IMgaSet",
+	gme_constants.OBJTYPE_FOLDER: "IMgaFolder",
+#	gme_constants.OBJTYPE_ASPECT: "IMgaAspect",
+#	gme_constants.OBJTYPE_ROLE: "IMgaRole",
+	gme_constants.OBJTYPE_ATTRIBUTE: "IMgaAttribute",
+	gme_constants.OBJTYPE_PART: "IMgaPart",
+}
+
+def cast(fco):
+	return win32com.client.CastTo(fco, OBJTYPE_INTERFACE_MAP.get(fco.ObjType))
+
+# KMS I'm not sure why gen_py lowercases these (for GME<VS2010). Create aliases:
+if mga_module.IMgaReference._prop_map_get_.has_key("referred"):
+    mga_module.IMgaReference._prop_map_get_["Referred"] = mga_module.IMgaReference._prop_map_get_["referred"]
+mga_module.IMgaConnPoint._prop_map_get_["Target"] = mga_module.IMgaConnPoint._prop_map_get_["target"]
+# Make IMgaFolder behave more like IMgaFCO
+mga_module.IMgaFolder._prop_map_get_["Meta"] = mga_module.IMgaFolder._prop_map_get_["MetaFolder"]
+
+
+def monkeypatch_method(classes):
+    def decorator(func):
+    	for name in classes:
+        	setattr(getattr(mga_module, name), func.__name__, func)
+        return func
+    return decorator
+
+# ConnPoints([out, retval] IMgaConnPoints **pVal);
+ at monkeypatch_method(["IMgaConnection"])
+def get_end(self, role):
+	ends = filter(lambda cp: cp.ConnRole == role, self.ConnPoints)
+	if ends:
+		return ends[0].Target
+	else:
+		raise Exception(self.Name + " has no connection point " + role)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def kind(self):
+    return self.Meta.Name
+
+OBJTYPE_MAP = {
+	gme_constants.OBJTYPE_MODEL: "Model",
+	gme_constants.OBJTYPE_ATOM: "Atom",
+	gme_constants.OBJTYPE_REFERENCE: "Reference",
+	gme_constants.OBJTYPE_CONNECTION: "Connection",
+	gme_constants.OBJTYPE_SET: "Set",
+	gme_constants.OBJTYPE_FOLDER: "Folder",
+	gme_constants.OBJTYPE_ASPECT: "Aspect",
+	gme_constants.OBJTYPE_ROLE: "Role",
+	gme_constants.OBJTYPE_ATTRIBUTE: "Attribute",
+	gme_constants.OBJTYPE_PART: "Part",
+}
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def mga_type(self):
+	return OBJTYPE_MAP.get(self.ObjType)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def parent(self):
+	if self.mga_type() == "Folder":
+		return self.ParentFolder
+	parent = self.ParentFolder
+	if not parent:
+		parent = self.ParentModel
+	return parent
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def parents(self):
+	parents = []
+	current = self
+	while True:
+		parent = current.parent()
+		if not parent:
+			return parents
+		else:
+			current = parent
+			parents.append(parent)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def in_library(self):
+	return filter(lambda x: x.mga_type() == "Folder" and x.LibraryName != "", self.parents())
+
+ at monkeypatch_method(["IMgaFolder"])
+def children(self):
+	children = []
+	children.extend(self.ChildFolders)
+	children.extend(self.ChildFCOs)
+	return children
+
+ at monkeypatch_method(["IMgaModel"])
+def children(self):
+	return self.ChildFCOs
+
+def is_container(fco):
+	return fco.ObjType == gme_constants.OBJTYPE_MODEL or fco.ObjType == gme_constants.OBJTYPE_FOLDER
+
+import tempfile
+class Project():
+	def __init__(self, com_project):
+		self.project = com_project
+
+	def __enter__(self):
+		self.begin_transaction()
+		return self
+
+	def __exit__(self, exc_type, exc_value, traceback):
+		if self.project.ProjectStatus == 3 or self.project.ProjectStatus == 4:
+			if exc_type:
+				self.project.AbortTransaction()
+			else:
+				self.project.CommitTransaction()
+			if self.territory:
+				self.territory.Destroy()
+				self.territory = None
+		self.project.Close()
+
+	def get_fco(self, path):
+		path_a = path.split("/")
+		current = self.project.RootFolder
+		for name in path_a[0:-1]:
+			containers = filter(is_container, current.children())
+			matches = filter(lambda x: x.Name == name, containers)
+			if matches:
+				current = cast(matches[0])
+			else:
+				raise Exception("Cant find %s in path %s" % (name, path))
+		matches = filter(lambda x: x.Name == path_a[-1], current.children())
+		if matches:
+			return cast(matches[0])
+		else:
+			raise Exception("Cant find %s in path %s" % (path_a[-1], path))
+
+	def save(self, filename=None):
+		if not filename:
+			filename = self.file
+		self.project.CommitTransaction()
+		if self.territory:
+			self.territory.Destroy()
+			self.territory = None
+
+		extension = os.path.splitext(filename)[1]
+		if extension == ".mga":
+			self.project.Save("MGA=" + filename)
+		elif extension == ".xme":
+			dumper = win32com.client.DispatchEx("Mga.MgaDumper")
+			dumper.DumpProject(self.project, filename)
+		else:
+			raise Exception("Don't know how to save '%s'" % filename)
+		self.territory = self.project.BeginTransactionInNewTerr()
+	
+	def begin_transaction(self):
+		self.territory = self.project.BeginTransactionInNewTerr()
+
+	def commit_transaction(self):
+		self.project.CommitTransaction()
+		if self.territory:
+			self.territory.Destroy()
+			self.territory = None
+	
+	def run_interpreter_raw(self, interpreter, focusobj=None, selectedobj=None, param=0):
+		import ctypes
+		import comtypes.client
+		import comtypes.automation
+		import _ctypes
+		comtypes.client.GetModule(['{270B4F86-B17C-11D3-9AD1-00AA00B6FE26}', 1, 0]) # Mga Mga
+		comtypes.client.GetModule(["{461F30AE-3BF0-11D4-B3F0-005004D38590}", 1, 0]) # MgaUtil
+		#TODO: check for GME version compatibility
+		#TODO: CreateMgaComponent supports IDispatch wrapper ComponentProxy. do the same here
+		comp = comtypes.client.CreateObject(interpreter, interface=comtypes.gen.MGAUTILLib.IMgaComponentEx)
+		if interpreter == "MGA.Interpreter.MetaInterpreter":
+			# http://escher.isis.vanderbilt.edu/JIRA/browse/GME-252
+			comp.AddRef()
+
+		comp.InteractiveMode = False
+		p = get_ctypes_dispatch_from_win32com(self.project)
+
+		#TODO: convert and use focusobj and selectedobj
+		fcos = comtypes.client.CreateObject("Mga.MgaFCOs")
+		self.commit_transaction()
+		try:
+			# FIXME: does this leak p ?
+			comp.InvokeEx(p.QueryInterface(comtypes.gen.MGALib.IMgaProject), None, fcos, 128)
+		finally:
+			self.begin_transaction()
+
+	
+	def run_interpreter(self, interpreter, focusobj=None, selectedobj=None, param=0):
+		if not selectedobj:
+			selectedobj=win32com.client.DispatchEx("Mga.MgaFCOs")
+		try:
+			self.run_interpreter_raw(interpreter, focusobj, selectedobj, param)
+		except ImportError:
+			print "Warning: no comtypes library. Running interpreter through MgaLauncher; interpreter return code will be lost"
+			self.commit_transaction()
+			try:
+				launcher = win32com.client.DispatchEx("Mga.MgaLauncher")
+				launcher.RunComponent(interpreter, self.project, focusobj, selectedobj, param)
+			finally:
+				self.begin_transaction()
+
+	@staticmethod
+	def create(mgafile, paradigm):
+		project = win32com.client.DispatchEx("Mga.MgaProject")
+		create_project(project, "MGA=" + mgafile, paradigm)
+		p = Project(project)
+		p.filename = mgafile
+		p.mgafile = mgafile
+		return p
+
+	@staticmethod
+	def open(file, mga_to_save=None):
+		if not os.path.isfile(file):
+			raise Exception("'" + file + "' not found")
+		extension = os.path.splitext(file)[1]
+		mga = None
+		if extension == ".mga":
+			mga = win32com.client.DispatchEx("Mga.MgaProject")
+			mga.Open("MGA=" + file)
+			mga_to_save = file
+		elif extension == ".xme":
+			xme = win32com.client.DispatchEx("Mga.MgaParser")
+			(paradigm, parversion, parguid, basename, ver) = xme.GetXMLInfo(file)
+
+			mga = win32com.client.DispatchEx("Mga.MgaProject")
+			xme = win32com.client.DispatchEx("Mga.MgaParser")
+			if mga_to_save == True:
+				mga_to_save = os.path.splitext(file)[0] + ".mga"
+			elif not mga_to_save:
+				mga_to_save = tempfile.gettempdir() + "gmepy-%s.mga" % os.getpid()
+			create_project(mga, "MGA=" + mga_to_save, paradigm)
+			xme.ParseProject(mga, file)
+		else:
+			raise Exception("Don't know how to open '%s'" % file)
+		p = Project(mga)
+		p.filename = file
+		p.mgafile = mga_to_save
+		return p
+
+def get_ctypes_dispatch_from_win32com(disp):
+	# http://mail.python.org/pipermail/python-win32/2008-April/007302.html
+	import win32com.client.dynamic
+	import ctypes
+	import comtypes
+	disp = win32com.client.dynamic.DumbDispatch(disp)
+	x = disp._oleobj_
+	addr = int(repr(x).split()[-1][2:-1], 16)
+	#print hex(addr)
+	
+	pnt = ctypes.POINTER(comtypes.automation.IDispatch)()
+	ctypes.cast(ctypes.byref(pnt), ctypes.POINTER(ctypes.c_void_p))[0] = addr
+	pnt.AddRef()
+	return pnt
+
+
+def print_paradigm(xmefile):
+	"Print the input file and paradigm of a given xme"
+	xme = win32com.client.DispatchEx("Mga.MgaParser")
+	(paradigm, parversion, parguid, basename, ver) = xme.GetXMLInfo(xmefile)
+	print xmefile
+	print paradigm
+
+import traceback
+if __name__ == '__main__':
+	try:
+		if sys.argv[1] not in dir():
+			gme_dict = sys.modules[__name__].__dict__
+			names = []
+			names.extend(gme_dict.keys())
+			for name in filter(lambda name: type(gme_dict[name]) == type(print_paradigm), names):
+				if gme_dict[name].__doc__:
+					print name
+					print "\t" + gme_dict[name].__doc__
+			sys.exit(1)
+		else:
+			# TRY:
+			# sys.modules[__name__].__getattribute__(sys.argv[1]).__call__(*sys.argv[2:])
+			eval("%s(*sys.argv[2:])" % sys.argv[1])
+	except:
+		traceback.print_exc(file=sys.stderr)
+		sys.stdin.readline()
+		sys.exit(1)

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/mgadiff.py (from r1070, trunk/Tests/GPyUnit/GME-297/mgadiff.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/mgadiff.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-297/mgadiff.py)
@@ -0,0 +1,241 @@
+import sys
+import gme
+import gc
+import os
+
+
+
+def compare (file1, file2):
+    with gme.Project.open(file1) as project1:
+        with gme.Project.open(file2) as project2:
+            return compare2(project1, project2)
+
+
+def iter_parents(fco):
+    while fco:
+        yield fco
+        fco = fco.parent()
+
+def fco_path(fco):
+    parents = list(iter_parents(fco))
+    parents.reverse()
+    return "/".join(map(lambda x: x.Name, parents))
+
+def compare2(project1, project2):
+    toProcess1=[]
+    toProcess2=[]
+    
+    current1=None
+    current2=None
+    
+    project1Root=project1.project.RootFolder
+    toProcess1.append(project1Root)
+    project2Root=project2.project.RootFolder
+    toProcess2.append(project2Root)
+    
+    current1=toProcess1.pop()
+
+    while current1!=None:
+        current1 = gme.cast(current1)
+        if len(toProcess2)==0:
+            print "Print nothing to process for " + current2.Name
+            return False
+
+        for index in range(len(toProcess2)):
+            current2 = gme.cast(toProcess2[index])
+            namesEqual = current1.Name == current2.Name
+            kindsEqual = current1.Meta.Name == current2.Meta.Name
+            connectionEndpointsEqual = True
+            if current1.ObjType == 4 and current2.ObjType == 4:
+                def mapConnpoints(conn):
+                    ret = map(lambda point: (point.ConnRole, [fco_path(point.target), map(fco_path, point.References)]), conn.ConnPoints)
+                    return dict(ret)
+                connectionEndpointsEqual = mapConnpoints(current1) == mapConnpoints(current2)
+                # Debugging aid:
+                #print "1 " + str(mapConnpoints(current1))
+                #print "2 " + str(mapConnpoints(current2))
+            if namesEqual and kindsEqual and connectionEndpointsEqual:
+                toProcess2.remove(current2)
+                break
+        else:
+            print "Found nothing corresponding to " + fco_path(current1) +" of kind \"" +gme.kind(current1) +"\""
+            return False
+        
+        if current1.AbsPath!=current2.AbsPath and current1.Name !=current2.Name :
+            # FIXME: KMS: AbsPath includes "relpos". Could this lead to false negatives?
+            print current1.AbsPath," != ",current2.AbsPath
+            return False
+        
+        if current1.ObjType != current2.ObjType:
+            print "'%s' has differing object types" % current1.AbsPath
+            return False
+
+        if current1.Meta.Name != current2.Meta.Name:
+            print "'%s' has differing kinds" % current1.AbsPath
+            return False
+
+        #FCO: attributes
+        if current1.ObjType != 6:
+            if not compareAttrib(current1, current2):
+                return False
+        
+        #ATOMS
+        if current1.ObjType == current2.ObjType and current2.ObjType ==2 :
+            if compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Atoms:: Wrong"
+                        return False
+                current2=None
+                continue
+            else:
+                return False
+        
+        
+        #REFERENCE
+        if current1.ObjType == 3 and current2.ObjType == 3 :
+            if compareReference(current1,current2) and compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Reference has something"
+                        return False
+                current2=None
+                continue
+            else:
+                print "compareReference FAILED for "+current1.Name+" "+current2.Name
+                return False
+        
+        
+        #Sets
+        if current1.ObjType == 5 and current2.ObjType == 5:
+            if compareSet(current1,current2)and compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Set 2 has something"
+                        return False
+                current2=None
+                continue
+            else:
+                print "compareSet FAILED for "+current1.Name+" "+current2.Name
+                return False
+        
+        if current1.ObjType == 1 and current2.ObjType == 1:
+            if not compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                return False
+        
+        #For FCO's that are connections we need to execute just this "if" block
+        if current1.ObjType == 4 and current2.ObjType == 4:
+            try:
+                current1=toProcess1.pop(0)
+            except IndexError:
+                if len(toProcess2) == 0:
+                    return True
+                else:
+                    print "CONNECTION:: Proc 2 has something"
+                    return False
+            current2=None
+            continue
+        
+        
+        childrenSet1=current1.children()
+        childrenSet2=current2.children()
+        toProcess1.extend(childrenSet1)
+        toProcess2.extend(childrenSet2)
+        
+        if len(childrenSet1)!= len(childrenSet2):
+            print "LENGTH of childrenSet FAILED for " + fco_path(current1)
+            print "\t" + "File 1: " + ", ".join([child.Name for child in current1.children()])
+            print "\t" + "File 2: " + ", ".join([child.Name for child in current2.children()])
+            return False
+        
+        if current1.ObjType == 6 and current2.ObjType == 6:
+            toProcess1.extend(gme.cast(current1).ChildFolders)
+            toProcess2.extend(gme.cast(current2).ChildFolders)
+
+        try:
+            current1=toProcess1.pop(0)
+        except IndexError:
+            if len(toProcess2) == 0:
+                return True
+            else:
+                print "END Proc 2 has something"
+                return False
+        continue
+
+def compareSet(*setFCOs):
+    array=[]
+    for index in range(len(setFCOs)):
+        array.append(dict())
+        array[index][setFCOs[index].Name]=setFCOs[index].AbsPath
+    
+    for index in range(len(setFCOs)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+
+def compareReference(*referenceFCOs):
+    array=[]
+    for index in range(len(referenceFCOs)):
+        array.append(dict())
+        array[index][referenceFCOs[index].Name]=referenceFCOs[index].AbsPath
+    
+    for index in range(len(referenceFCOs)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+   
+def compareAssoc(*current):
+    array=[]
+    for index in range(len(current)):
+        array.append(dict())
+        for point in current[index]:
+            array[index][point.ConnRole]="%s %s" % (point.target.Name,point.target.AbsPath)
+    
+    for index in range(len(current)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+
+def compareAttrib(fco1, fco2):
+    def mapAttribs(fco):
+        ret = map(lambda attr: (attr.Meta.Name, attr.Value), fco.Attributes)
+        return dict(ret)
+    fco1Attribs = mapAttribs(fco1)
+    fco2Attribs = mapAttribs(fco2)
+    if fco1Attribs != fco2Attribs:
+        print "'%s' has differing attributes:" % fco1.AbsPath
+        unequalkeys = filter(lambda key: fco1Attribs.get(key) != fco2Attribs.get(key), fco1Attribs.keys())
+        print "\n".join(map(lambda key: "Name: %s: '%s' != '%s' " % (key, fco1Attribs.get(key), fco2Attribs.get(key)), unequalkeys))
+        return False
+    return True
+
+if __name__ == "__main__":
+
+    if(len(sys.argv)==3):
+        file1=sys.argv[1]
+        file2=sys.argv[2]
+        if not os.path.isfile(file1):
+            print False
+        os.path.isfile(file2)
+        if(compare(file1,file2)):
+            print "'%s','%s' are the same" % (file1, file2)
+        else:
+            print "'%s','%s' are not the same" % (file1, file2)
+        gc.collect()
+    else:
+        print "Need exactly two arguments"
\ No newline at end of file

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test.py (from r1070, trunk/Tests/GPyUnit/GME-297/test.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-297/test.py)
@@ -0,0 +1,57 @@
+# tests for GME-311 and GME-297
+
+import sys
+import os.path
+import unittest
+import win32com.client
+
+class TestRefportConnectionInvariantUnderMoves(unittest.TestCase):
+    def __init__(self, input_file, fco_to_move, destination_model, name=None):
+        unittest.TestCase.__init__(self, 'test')
+        self.input_file = input_file
+        self.fco_to_move = fco_to_move
+        self.destination_model = destination_model
+        name = name if name else os.path.splitext(self.input_file)[0]
+        self.output_file = name + "-output.mga"
+        self.correct_file = name + "-correct.mga"
+
+    def test(self):
+        '''
+        Regression test: given self.input_file, move self.fco_to_move to self.destination_model. Then check self.output_file against self.correct_file
+        '''
+        # This script depends on late binding. win32com.client.dynamic.Dispatch forces late binding when creating an object,
+        # but early-bound objects may be returned from function calls. Disable late binding completely.
+        import win32com.client.gencache
+        _savedGetClassForCLSID = win32com.client.gencache.GetClassForCLSID
+        win32com.client.gencache.GetClassForCLSID = lambda x: None
+
+        self.project = win32com.client.DispatchEx("Mga.MgaProject")
+        self.project.Open("MGA=" + self.input_file)
+        self.territory = self.project.BeginTransactionInNewTerr()
+
+        modelb = self.project.ObjectByPath(self.fco_to_move)
+        modelb.Name
+        tomove = win32com.client.DispatchEx("Mga.MgaFCOs")
+        tomove.Append(modelb)
+        self.project.ObjectByPath(self.destination_model).MoveFCOs(tomove, None, None)
+
+        self.project.CommitTransaction()
+        self.project.Save("MGA=" + self.output_file)
+        self.territory.Destroy()
+
+        win32com.client.gencache.GetClassForCLSID = _savedGetClassForCLSID
+        import mgadiff
+        if not mgadiff.compare(self.correct_file, self.output_file):
+            self.fail("Reference file '%s' does not match output '%s'" % (self.correct_file, self.output_file))
+        #print "Reference file '%s' matches output '%s'" % (self.correct_file, self.output_file)
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(TestRefportConnectionInvariantUnderMoves(input_file="test1.mga", fco_to_move="/Test1/Folder1/A/B", destination_model="/Test1/Folder2/C"))
+    suite.addTest(TestRefportConnectionInvariantUnderMoves(input_file="test2.mga", fco_to_move="/Test2/Subtypes/A/BSubtypeRef", destination_model="/Test2/Destination/Destination"))
+    suite.addTest(TestRefportConnectionInvariantUnderMoves(input_file="test1.mga", fco_to_move="/Test1/Folder1/A/RefB", destination_model="/Test1/Folder2/C", name="test3"))
+    return suite
+
+if __name__ == "__main__":
+    runner = unittest.TextTestRunner()
+    runner.run(suite())

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test1-correct.mga (from r1070, trunk/Tests/GPyUnit/GME-297/test1-correct.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test1.mga (from r1070, trunk/Tests/GPyUnit/GME-297/test1.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test2-correct.mga (from r1070, trunk/Tests/GPyUnit/GME-297/test2-correct.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test2.mga (from r1070, trunk/Tests/GPyUnit/GME-297/test2.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-297/test3-correct.mga (from r1070, trunk/Tests/GPyUnit/GME-297/test3-correct.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/GME310ModelRefportTest.mga (from r1070, trunk/Tests/GPyUnit/GME-310/GME310ModelRefportTest.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp (from r1070, trunk/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-310/GME310ModelRefportTest.xmp)
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!DOCTYPE paradigm SYSTEM "edf.dtd">
+
+<paradigm name="GME310ModelRefportTest" guid="{4D75F5CC-0720-4B67-81B2-397E580F0B85}" cdate="Thu Sep 23 11:45:28 2010" mdate="Thu Sep 23 11:45:28 2010" >
+
+	<comment></comment>
+
+	<author></author>
+
+	<folder name = "RootFolder" metaref = "1000"  subfolders = "KindFolder" >
+		<atom name = "KindAtom" metaref = "1001" >
+				<regnode name = "namePosition" value ="4"></regnode>
+		</atom>
+		<connection name = "KindConnection" metaref = "1002" >
+				<regnode name = "color" value ="0x000000"></regnode>
+				<regnode name = "dstStyle" value ="arrow"></regnode>
+				<regnode name = "srcStyle" value ="butt"></regnode>
+				<regnode name = "lineType" value ="solid"></regnode>
+			<connjoint>
+				<pointerspec name = "src">
+					<pointeritem desc = "KindAtom"></pointeritem>
+					<pointeritem desc = "KindModel KindAtom"></pointeritem>
+					<pointeritem desc = "KindModelReference KindAtom"></pointeritem>
+				</pointerspec>
+				<pointerspec name = "dst">
+					<pointeritem desc = "KindAtom"></pointeritem>
+					<pointeritem desc = "KindModel KindAtom"></pointeritem>
+					<pointeritem desc = "KindModelReference KindAtom"></pointeritem>
+				</pointerspec>
+			</connjoint>
+		</connection>
+		<reference name = "KindModelReference" metaref = "1003">
+				<regnode name = "namePosition" value ="4"></regnode>
+			<pointerspec name = "ref">
+				<pointeritem desc = "KindModel"></pointeritem>
+				<pointeritem desc = "KindModelReference"></pointeritem>
+			</pointerspec>
+		</reference>
+		<model name = "KindModel" metaref = "1004" >
+				<regnode name = "namePosition" value ="4"></regnode>
+				<regnode name = "isTypeInfoShown" value ="true"></regnode>
+			<role name = "KindAtom" metaref = "1005" kind = "KindAtom"></role>
+			<role name = "KindConnection" metaref = "1013" kind = "KindConnection"></role>
+			<role name = "KindModel" metaref = "1011" kind = "KindModel"></role>
+			<role name = "KindModelReference" metaref = "1006" kind = "KindModelReference"></role>
+			<aspect name = "KindAspect" metaref = "1007" >
+				<part metaref = "1008" role = "KindAtom" primary = "yes" linked = "yes"></part>
+				<part metaref = "1014" role = "KindConnection" primary = "yes" linked = "no"></part>
+				<part metaref = "1012" role = "KindModel" primary = "yes" linked = "no"></part>
+				<part metaref = "1009" role = "KindModelReference" primary = "yes" kindaspect = "KindAspect" linked = "no"></part>
+			</aspect>
+		</model>
+		<folder name = "KindFolder" metaref = "1010"  subfolders = "KindFolder" rootobjects = "KindModel" >
+		</folder>
+	</folder>
+</paradigm>

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/gme.py (from r1070, trunk/Tests/GPyUnit/GME-310/gme.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/gme.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-310/gme.py)
@@ -0,0 +1,605 @@
+#!/bin/python
+
+import re
+import sys
+import os.path
+import pythoncom
+import win32com.client
+import StringIO
+# For py2exe support
+# To generate the exe, be sure to rename or delete .../Python/lib/site-packages/win32com/gen_py
+# See http://www.py2exe.org/index.cgi/UsingEnsureDispatch
+if win32com.client.gencache.is_readonly == True:
+	#allow gencache to create the cached wrapper objects
+	win32com.client.gencache.is_readonly = False
+	# under p2exe the call in gencache to __init__() does not happen
+	# so we use Rebuild() to force the creation of the gen_py folder
+	try:
+		saveout = sys.stdout
+		try:
+			sys.stdout = output = StringIO.StringIO()
+			win32com.client.gencache.Rebuild()
+		finally:
+			sys.stdout = saveout
+	except:
+		print output.getvalue()
+		raise
+
+import pywintypes
+import subprocess
+import itertools
+
+# Elevation helpers
+def execute_elevated(*args):
+	# FIXME: support **kwargs
+	from win32com.shell.shell import ShellExecuteEx
+	from win32com.shell import shellcon
+	import win32process, win32event
+	import winxpgui
+	import win32api
+	import win32con
+	try:
+		hwnd = winxpgui.GetConsoleWindow()
+	except winxpgui.error:
+		hwnd = 0
+	parameters = ""
+	if not hasattr(sys, "frozen"):
+		# Not running under py2exe exe
+		parameters += "\"" + sys.argv[0] + "\" "
+	parameters += " ".join(map(lambda x: "\"" + str(x) + "\"", args))
+	print "Executing elevated with parameters " + parameters
+	# TODO: capture output (maybe via named pipe)
+	rc = ShellExecuteEx(hwnd=hwnd, fMask=shellcon.SEE_MASK_NOCLOSEPROCESS, lpVerb="runas", lpFile=sys.executable, 
+		lpParameters=parameters, nShow=win32con.SW_SHOW)
+	hproc = rc['hProcess']
+	win32event.WaitForSingleObject(hproc, win32event.INFINITE)
+	exit_code = win32process.GetExitCodeProcess(hproc)
+	if exit_code:
+		raise Exception("Error: subprocess failed (exit code %s)." % exit_code)
+
+def is_elevated():
+	import win32security
+	import win32api
+	hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_QUERY)
+	return win32security.GetTokenInformation(hToken, win32security.TokenElevation) != 0
+
+
+def maybe_elevate():
+	def decorator(func):
+		if sys.getwindowsversion()[0] < 6:
+			wrap = func
+		else:
+			def wrap(*args, **kwargs):
+				if not is_elevated():
+					execute_elevated(func.__name__, *args, **kwargs)
+				else:
+					func(*args, **kwargs)
+		setattr(sys.modules[__name__], func.__name__, wrap)
+		return wrap
+	return decorator
+
+ at maybe_elevate()
+def elevated_check_call(*args):
+	return subprocess.check_call(args)
+
+# GME functions
+def create_project(project, connection, paradigm):
+		try:
+			return project.Create(connection, paradigm)
+		except pywintypes.com_error as err:
+# from Mga.idl:
+#[helpstring("The paradigm is not registered")]
+#		E_MGA_PARADIGM_NOTREG			= 0x87650011,
+			if err.excepinfo and err.excepinfo[5] == -2023423983:
+				raise Exception("Paradigm '%s' not registered; can't open file '%s'" % (paradigm, connection), err)
+			raise err
+
+# aka CreateMga.vbs
+def xme2mga(xmefile, mgafile=None):
+	if not mgafile:
+		mgafile = os.path.splitext(xmefile)[0] + ".mga"
+	with Project.open(xmefile, mgafile) as project:
+		project.save(project.mgafile)
+		return project.mgafile
+
+def run_interpreter(interpreter, file, focusobj=None, selectedobj=None, param=0, mga_to_save=None):
+	with Project.open(file, mga_to_save=mga_to_save) as project:
+		project.run_interpreter(interpreter, focusobj, selectedobj, param)
+
+# MGAUTILLib.regaccessmode_enum.REGACCESS_BOTH = 3
+def get_paradigm_file(paradigm, regaccess=3):
+	"Returns the .mta file for a given registered paradigm"
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	guid = registrar.ParadigmGUIDString(regaccess, paradigm)
+	import uuid
+	buf = buffer(uuid.UUID(guid).bytes_le, 0, 16)
+	(connstr, guid) = registrar.QueryParadigm(paradigm, None, buf, regaccess)
+	# >>> constr
+	# "MGA=....mta"
+	return connstr[4:]
+
+
+def _associate(progid, paradigm, regaccess):
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	registrar.Associate(progid, paradigm, regaccess)
+
+ at maybe_elevate()
+def _associate_elevated(*args):
+	_associate(*args)
+
+def associate(progid, paradigm, regaccess=1):
+	"Associate a component with a paradigm"
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_associate_elevated(progid, paradigm, regaccess)
+	else:
+		_associate(progid, paradigm, regaccess)
+
+
+def is_registered(paradigm):
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	paradigms = []
+	# REGACCESS_USER = 1
+	paradigms.extend(registrar.Paradigms(1))
+	# REGACCESS_SYSTEM = 2
+	paradigms.extend(registrar.Paradigms(2))
+	return filter(lambda p: p == paradigm, paradigms)
+
+REGISTER = 128
+DONT_REGISTER = 0
+def register_if_not_registered(file):
+	"Register an xme or mga if it has not already been registered"
+	if os.path.splitext(file)[1] == ".xmp":
+		if not is_registered(os.path.splitext(file)[0]):
+			regxmp(file)
+		return
+	
+	# if we don't give GME an absolute path, it registers the mta with a relative path (which is bad)
+	with Project.open(os.path.abspath(file), mga_to_save=True) as project:
+		paradigm = project.project.RootFolder.Name
+		if not is_registered(paradigm):
+			project.run_interpreter("MGA.Interpreter.MetaInterpreter", param=REGISTER)
+			print "Paradigm '%s' is now registered" % paradigm
+		elif not os.path.isfile(get_paradigm_file(paradigm)):
+			#FIXME: should we look for the .xmp?
+			project.run_interpreter("MGA.Interpreter.MetaInterpreter", param=REGISTER)
+			print "Paradigm '%s' had nonexistant .mta; it is now reregistered" % paradigm
+		# TODO: can we check if it is up-to-date?
+		# or os.path.getmtime(get_paradigm_file(paradigm)) < os.path.getmtime(file):
+		else:
+			print "Paradigm '%s' is already registered" % paradigm
+
+def mga2xmp(mgafile, register=REGISTER):
+	# if we don't give GME an absolute path, it registers the mta with a relative path (which is bad)
+	run_interpreter("MGA.Interpreter.MetaInterpreter", os.path.abspath(mgafile), param=register, mga_to_save=True)
+
+def xme2xmp(xmefile, register=REGISTER):
+	mgafile = xme2mga(xmefile)
+	mga2xmp(mgafile, register)
+	return mgafile
+
+def _regxmp(xmpfile, regaccess):
+	REG_USER = 1
+	REG_SYSTEM = 2
+	REG_BOTH = 3
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	registrar.RegisterParadigmFromData("XML=" + os.path.abspath(xmpfile), "", regaccess)
+
+ at maybe_elevate()
+def _regxmp_elevated(xmpfile, regaccess):
+	_regxmp(xmpfile, regaccess)
+
+def regxmp(xmpfile, regaccess=1):
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_regxmp_elevated(xmpfile, regaccess)
+	else:
+		_regxmp(xmpfile, regaccess)
+
+def _reggmexmps(regaccess):
+	regaccess = int(regaccess)
+	for file in [ 'HFSM/HFSM.xmp', 'MetaGME/Paradigm/MetaGME.xmp', 'SF/SF.xmp', 'UML/UML.xmp' ]:
+		regxmp(os.path.join(os.path.join(os.environ['GME_ROOT'], 'Paradigms'), file), regaccess)
+
+ at maybe_elevate()
+def _reggmexmps_elevated(regaccess):
+	_reggmexmps(regaccess)
+
+def reggmexmps(regaccess=1):
+	regaccess = int(regaccess)
+	if regaccess != 1:
+		_reggmexmps_elevated(regaccess)
+	else:
+		_reggmexmps(regaccess)
+
+def mga2xme(mgafile, xmefile=None):
+	if not xmefile:
+		xmefile = os.path.splitext(mgafile)[0] + ".xme"
+
+	with Project.open(mgafile) as project:
+		project.save(xmefile)
+	return xmefile
+
+def register_component(file, warn_on_tlb_error=None):
+# TODO: on Vista or 7 we need to start an elevated registrar
+	registrar = win32com.client.DispatchEx("Mga.MgaRegistrar")
+	# REGACCESS_BOTH	= 3,
+	try:
+		registrar.RegisterComponentLibrary(file, 3)
+	except pywintypes.com_error as err:
+# KMS: GME assumes that the .dll has a type library. If it is a CLR component, it will not.
+# Warn if the type library registration fails
+# #define TYPE_E_CANTLOADLIBRARY _HRESULT_TYPEDEF_(0x80029C4AL)
+		if warn_on_tlb_error and err.excepinfo and (err.excepinfo[5] & 0xffffffff == 0x80029c4a):
+			sys.stderr.write("Type library registration for %s failed" % file);
+		else:
+			raise err
+
+
+# UDM functions
+def meta2uml(mgafile, umlfile=None):
+	if not os.path.isfile(mgafile):
+		raise Exception("'" + mgafile + "' not found")
+	
+	if not umlfile:
+		umlfile = os.path.splitext(mgafile)[0] + "_uml.mga"
+	subprocess.check_call(["MetaGME2UML.exe", mgafile, umlfile])
+
+# aka CreateUdmXml.vbs
+def mga2udmxml(mgafile):
+	run_interpreter("MGA.Interpreter.UML2XML", mgafile, None, None, 128)
+
+# GReAT functions
+def RunGreatMasterInt(file):
+	file = os.path.abspath(file)
+	with Project.open(file) as project:
+		project.run_interpreter("MGA.Interpreter.GReAT Master Interpreter", param=128)
+# touch(1) the generated .udm file so incremental build works
+		configurations = (cast(fco) for fco in project.project.RootFolder.children() if fco.kind() == "Configurations").next()
+		configuration = (cast(fco) for fco in configurations.children() if fco.kind() == "Configuration").next()
+		metainformation = (cast(fco) for fco in configuration.children() if fco.kind() == "MetaInformation").next()
+		udmfile = os.path.dirname(file) + "/" + metainformation.AttributeByName("UdmProjectFile")
+		mtime = os.stat(udmfile).st_mtime
+	os.utime(file, (mtime, mtime))
+
+# Explorer context menu
+def context_menu_reg():
+	"""Register explorer context menu options"""
+	import _winreg
+	if hasattr(sys, "frozen"):
+		# Running under py2exe exe
+		gmepydir = os.path.dirname(unicode(sys.executable, sys.getfilesystemencoding( )))
+	else:
+		gmepydir = os.path.dirname(__file__)
+	# Windows won't let us start gme.py from the context menu, so use the exe
+	gmepy = gmepydir + "\\gmepy.exe"
+
+	mga = "mga"
+	xme = "xme"
+	xmp = "xmp"
+	menus = [ (mga, "mga2xme"),
+			(mga, "mga2xmp"),
+			(mga, "mga2udmxml"),
+			(xme, "xme2mga"),
+			(xmp, "regxmp"),
+			]
+	regname = gmepydir + "\\gmepy_context_menu.reg"
+	with open(regname, "w") as reg:
+		reg.write("Windows Registry Editor Version 5.00\n")
+		for p in menus:
+			try:
+				key = _winreg.OpenKey(_winreg.ConnectRegistry(None, _winreg.HKEY_CLASSES_ROOT), "."+p[0])
+				n,v,t = _winreg.EnumValue(key, 0)
+				ext = v
+				_winreg.CloseKey(key)
+			except WindowsError:
+				ext = "."+p[0]
+			str = """[HKEY_CLASSES_ROOT\{ext}\shell]
+
+[HKEY_CLASSES_ROOT\{ext}\shell\{name}]
+
+[HKEY_CLASSES_ROOT\{ext}\shell\{name}\command]
+@="\\"{gmepy}\\" {name} \\\"%1\\\""
+
+""".format(ext=ext, name=p[1], gmepy=gmepy.replace("\\", "\\\\"))
+			reg.write(str)
+	elevated_check_call("regedit", regname)
+
+
+# GME Project functions
+import win32com.client.gencache
+# Generate .py's for GME Type Library
+# n.b. we don't use EnsureModule here because we don't properly version the typelib
+#   A change in the typelib may invalidate the cache, but gencache doesn't know it, e.g. GMESRC r947
+meta_module = win32com.client.gencache.MakeModuleForTypelib('{0ADEEC71-D83A-11D3-B36B-005004D38590}', 0, 1, 0)
+mga_module = win32com.client.gencache.MakeModuleForTypelib('{270B4F86-B17C-11D3-9AD1-00AA00B6FE26}', 0, 1, 0)
+
+gme_constants = getattr(meta_module, "constants")
+
+OBJTYPE_INTERFACE_MAP = {
+	gme_constants.OBJTYPE_MODEL: "IMgaModel",
+	# Seems IMgaAtom isn't generated because it defines no new methods
+#	2: "IMgaAtom",
+	gme_constants.OBJTYPE_ATOM: "IMgaFCO",
+	gme_constants.OBJTYPE_REFERENCE: "IMgaReference",
+	gme_constants.OBJTYPE_CONNECTION: "IMgaConnection",
+	gme_constants.OBJTYPE_SET: "IMgaSet",
+	gme_constants.OBJTYPE_FOLDER: "IMgaFolder",
+#	gme_constants.OBJTYPE_ASPECT: "IMgaAspect",
+#	gme_constants.OBJTYPE_ROLE: "IMgaRole",
+	gme_constants.OBJTYPE_ATTRIBUTE: "IMgaAttribute",
+	gme_constants.OBJTYPE_PART: "IMgaPart",
+}
+
+def cast(fco):
+	return win32com.client.CastTo(fco, OBJTYPE_INTERFACE_MAP.get(fco.ObjType))
+
+# KMS I'm not sure why gen_py lowercases these (for GME<VS2010). Create aliases:
+if mga_module.IMgaReference._prop_map_get_.has_key("referred"):
+    mga_module.IMgaReference._prop_map_get_["Referred"] = mga_module.IMgaReference._prop_map_get_["referred"]
+mga_module.IMgaConnPoint._prop_map_get_["Target"] = mga_module.IMgaConnPoint._prop_map_get_["target"]
+# Make IMgaFolder behave more like IMgaFCO
+mga_module.IMgaFolder._prop_map_get_["Meta"] = mga_module.IMgaFolder._prop_map_get_["MetaFolder"]
+
+
+def monkeypatch_method(classes):
+    def decorator(func):
+    	for name in classes:
+        	setattr(getattr(mga_module, name), func.__name__, func)
+        return func
+    return decorator
+
+# ConnPoints([out, retval] IMgaConnPoints **pVal);
+ at monkeypatch_method(["IMgaConnection"])
+def get_end(self, role):
+	ends = filter(lambda cp: cp.ConnRole == role, self.ConnPoints)
+	if ends:
+		return ends[0].Target
+	else:
+		raise Exception(self.Name + " has no connection point " + role)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def kind(self):
+    return self.Meta.Name
+
+OBJTYPE_MAP = {
+	gme_constants.OBJTYPE_MODEL: "Model",
+	gme_constants.OBJTYPE_ATOM: "Atom",
+	gme_constants.OBJTYPE_REFERENCE: "Reference",
+	gme_constants.OBJTYPE_CONNECTION: "Connection",
+	gme_constants.OBJTYPE_SET: "Set",
+	gme_constants.OBJTYPE_FOLDER: "Folder",
+	gme_constants.OBJTYPE_ASPECT: "Aspect",
+	gme_constants.OBJTYPE_ROLE: "Role",
+	gme_constants.OBJTYPE_ATTRIBUTE: "Attribute",
+	gme_constants.OBJTYPE_PART: "Part",
+}
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def mga_type(self):
+	return OBJTYPE_MAP.get(self.ObjType)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def parent(self):
+	if self.mga_type() == "Folder":
+		return self.ParentFolder
+	parent = self.ParentFolder
+	if not parent:
+		parent = self.ParentModel
+	return parent
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def parents(self):
+	parents = []
+	current = self
+	while True:
+		parent = current.parent()
+		if not parent:
+			return parents
+		else:
+			current = parent
+			parents.append(parent)
+
+ at monkeypatch_method(itertools.chain(["IMgaFCO"], OBJTYPE_INTERFACE_MAP.itervalues()))
+def in_library(self):
+	return filter(lambda x: x.mga_type() == "Folder" and x.LibraryName != "", self.parents())
+
+ at monkeypatch_method(["IMgaFolder"])
+def children(self):
+	children = []
+	children.extend(self.ChildFolders)
+	children.extend(self.ChildFCOs)
+	return children
+
+ at monkeypatch_method(["IMgaModel"])
+def children(self):
+	return self.ChildFCOs
+
+def is_container(fco):
+	return fco.ObjType == gme_constants.OBJTYPE_MODEL or fco.ObjType == gme_constants.OBJTYPE_FOLDER
+
+import tempfile
+class Project():
+	def __init__(self, com_project):
+		self.project = com_project
+
+	def __enter__(self):
+		self.begin_transaction()
+		return self
+
+	def __exit__(self, exc_type, exc_value, traceback):
+		if self.project.ProjectStatus == 3 or self.project.ProjectStatus == 4:
+			if exc_type:
+				self.project.AbortTransaction()
+			else:
+				self.project.CommitTransaction()
+			if self.territory:
+				self.territory.Destroy()
+				self.territory = None
+		self.project.Close()
+
+	def get_fco(self, path):
+		path_a = path.split("/")
+		current = self.project.RootFolder
+		for name in path_a[0:-1]:
+			containers = filter(is_container, current.children())
+			matches = filter(lambda x: x.Name == name, containers)
+			if matches:
+				current = cast(matches[0])
+			else:
+				raise Exception("Cant find %s in path %s" % (name, path))
+		matches = filter(lambda x: x.Name == path_a[-1], current.children())
+		if matches:
+			return cast(matches[0])
+		else:
+			raise Exception("Cant find %s in path %s" % (path_a[-1], path))
+
+	def save(self, filename=None):
+		if not filename:
+			filename = self.file
+		self.project.CommitTransaction()
+		if self.territory:
+			self.territory.Destroy()
+			self.territory = None
+
+		extension = os.path.splitext(filename)[1]
+		if extension == ".mga":
+			self.project.Save("MGA=" + filename)
+		elif extension == ".xme":
+			dumper = win32com.client.DispatchEx("Mga.MgaDumper")
+			dumper.DumpProject(self.project, filename)
+		else:
+			raise Exception("Don't know how to save '%s'" % filename)
+		self.territory = self.project.BeginTransactionInNewTerr()
+	
+	def begin_transaction(self):
+		self.territory = self.project.BeginTransactionInNewTerr()
+
+	def commit_transaction(self):
+		self.project.CommitTransaction()
+		if self.territory:
+			self.territory.Destroy()
+			self.territory = None
+	
+	def run_interpreter_raw(self, interpreter, focusobj=None, selectedobj=None, param=0):
+		import ctypes
+		import comtypes.client
+		import comtypes.automation
+		import _ctypes
+		comtypes.client.GetModule(['{270B4F86-B17C-11D3-9AD1-00AA00B6FE26}', 1, 0]) # Mga Mga
+		comtypes.client.GetModule(["{461F30AE-3BF0-11D4-B3F0-005004D38590}", 1, 0]) # MgaUtil
+		#TODO: check for GME version compatibility
+		#TODO: CreateMgaComponent supports IDispatch wrapper ComponentProxy. do the same here
+		comp = comtypes.client.CreateObject(interpreter, interface=comtypes.gen.MGAUTILLib.IMgaComponentEx)
+		if interpreter == "MGA.Interpreter.MetaInterpreter":
+			# http://escher.isis.vanderbilt.edu/JIRA/browse/GME-252
+			comp.AddRef()
+
+		comp.InteractiveMode = False
+		p = get_ctypes_dispatch_from_win32com(self.project)
+
+		#TODO: convert and use focusobj and selectedobj
+		fcos = comtypes.client.CreateObject("Mga.MgaFCOs")
+		self.commit_transaction()
+		try:
+			# FIXME: does this leak p ?
+			comp.InvokeEx(p.QueryInterface(comtypes.gen.MGALib.IMgaProject), None, fcos, 128)
+		finally:
+			self.begin_transaction()
+
+	
+	def run_interpreter(self, interpreter, focusobj=None, selectedobj=None, param=0):
+		if not selectedobj:
+			selectedobj=win32com.client.DispatchEx("Mga.MgaFCOs")
+		try:
+			self.run_interpreter_raw(interpreter, focusobj, selectedobj, param)
+		except ImportError:
+			print "Warning: no comtypes library. Running interpreter through MgaLauncher; interpreter return code will be lost"
+			self.commit_transaction()
+			try:
+				launcher = win32com.client.DispatchEx("Mga.MgaLauncher")
+				launcher.RunComponent(interpreter, self.project, focusobj, selectedobj, param)
+			finally:
+				self.begin_transaction()
+
+	@staticmethod
+	def create(mgafile, paradigm):
+		project = win32com.client.DispatchEx("Mga.MgaProject")
+		create_project(project, "MGA=" + mgafile, paradigm)
+		p = Project(project)
+		p.filename = mgafile
+		p.mgafile = mgafile
+		return p
+
+	@staticmethod
+	def open(file, mga_to_save=None):
+		if not os.path.isfile(file):
+			raise Exception("'" + file + "' not found")
+		extension = os.path.splitext(file)[1]
+		mga = None
+		if extension == ".mga":
+			mga = win32com.client.DispatchEx("Mga.MgaProject")
+			mga.Open("MGA=" + file)
+			mga_to_save = file
+		elif extension == ".xme":
+			xme = win32com.client.DispatchEx("Mga.MgaParser")
+			(paradigm, parversion, parguid, basename, ver) = xme.GetXMLInfo(file)
+
+			mga = win32com.client.DispatchEx("Mga.MgaProject")
+			xme = win32com.client.DispatchEx("Mga.MgaParser")
+			if mga_to_save == True:
+				mga_to_save = os.path.splitext(file)[0] + ".mga"
+			elif not mga_to_save:
+				mga_to_save = tempfile.gettempdir() + "gmepy-%s.mga" % os.getpid()
+			create_project(mga, "MGA=" + mga_to_save, paradigm)
+			xme.ParseProject(mga, file)
+		else:
+			raise Exception("Don't know how to open '%s'" % file)
+		p = Project(mga)
+		p.filename = file
+		p.mgafile = mga_to_save
+		return p
+
+def get_ctypes_dispatch_from_win32com(disp):
+	# http://mail.python.org/pipermail/python-win32/2008-April/007302.html
+	import win32com.client.dynamic
+	import ctypes
+	import comtypes
+	disp = win32com.client.dynamic.DumbDispatch(disp)
+	x = disp._oleobj_
+	addr = int(repr(x).split()[-1][2:-1], 16)
+	#print hex(addr)
+	
+	pnt = ctypes.POINTER(comtypes.automation.IDispatch)()
+	ctypes.cast(ctypes.byref(pnt), ctypes.POINTER(ctypes.c_void_p))[0] = addr
+	pnt.AddRef()
+	return pnt
+
+
+def print_paradigm(xmefile):
+	"Print the input file and paradigm of a given xme"
+	xme = win32com.client.DispatchEx("Mga.MgaParser")
+	(paradigm, parversion, parguid, basename, ver) = xme.GetXMLInfo(xmefile)
+	print xmefile
+	print paradigm
+
+import traceback
+if __name__ == '__main__':
+	try:
+		if sys.argv[1] not in dir():
+			gme_dict = sys.modules[__name__].__dict__
+			names = []
+			names.extend(gme_dict.keys())
+			for name in filter(lambda name: type(gme_dict[name]) == type(print_paradigm), names):
+				if gme_dict[name].__doc__:
+					print name
+					print "\t" + gme_dict[name].__doc__
+			sys.exit(1)
+		else:
+			# TRY:
+			# sys.modules[__name__].__getattribute__(sys.argv[1]).__call__(*sys.argv[2:])
+			eval("%s(*sys.argv[2:])" % sys.argv[1])
+	except:
+		traceback.print_exc(file=sys.stderr)
+		sys.stdin.readline()
+		sys.exit(1)

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/mgadiff.py (from r1070, trunk/Tests/GPyUnit/GME-310/mgadiff.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/mgadiff.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-310/mgadiff.py)
@@ -0,0 +1,241 @@
+import sys
+import gme
+import gc
+import os
+
+
+
+def compare (file1, file2):
+    with gme.Project.open(file1) as project1:
+        with gme.Project.open(file2) as project2:
+            return compare2(project1, project2)
+
+
+def iter_parents(fco):
+    while fco:
+        yield fco
+        fco = fco.parent()
+
+def fco_path(fco):
+    parents = list(iter_parents(fco))
+    parents.reverse()
+    return "/".join(map(lambda x: x.Name, parents))
+
+def compare2(project1, project2):
+    toProcess1=[]
+    toProcess2=[]
+    
+    current1=None
+    current2=None
+    
+    project1Root=project1.project.RootFolder
+    toProcess1.append(project1Root)
+    project2Root=project2.project.RootFolder
+    toProcess2.append(project2Root)
+    
+    current1=toProcess1.pop()
+
+    while current1!=None:
+        current1 = gme.cast(current1)
+        if len(toProcess2)==0:
+            print "Print nothing to process for " + current2.Name
+            return False
+
+        for index in range(len(toProcess2)):
+            current2 = gme.cast(toProcess2[index])
+            namesEqual = current1.Name == current2.Name
+            kindsEqual = current1.Meta.Name == current2.Meta.Name
+            connectionEndpointsEqual = True
+            if current1.ObjType == 4 and current2.ObjType == 4:
+                def mapConnpoints(conn):
+                    ret = map(lambda point: (point.ConnRole, [fco_path(point.target), map(fco_path, point.References)]), conn.ConnPoints)
+                    return dict(ret)
+                connectionEndpointsEqual = mapConnpoints(current1) == mapConnpoints(current2)
+                # Debugging aid:
+                #print "1 " + str(mapConnpoints(current1))
+                #print "2 " + str(mapConnpoints(current2))
+            if namesEqual and kindsEqual and connectionEndpointsEqual:
+                toProcess2.remove(current2)
+                break
+        else:
+            print "Found nothing corresponding to " + fco_path(current1) +" of kind \"" +gme.kind(current1) +"\""
+            return False
+        
+        if current1.AbsPath!=current2.AbsPath and current1.Name !=current2.Name :
+            # FIXME: KMS: AbsPath includes "relpos". Could this lead to false negatives?
+            print current1.AbsPath," != ",current2.AbsPath
+            return False
+        
+        if current1.ObjType != current2.ObjType:
+            print "'%s' has differing object types" % current1.AbsPath
+            return False
+
+        if current1.Meta.Name != current2.Meta.Name:
+            print "'%s' has differing kinds" % current1.AbsPath
+            return False
+
+        #FCO: attributes
+        if current1.ObjType != 6:
+            if not compareAttrib(current1, current2):
+                return False
+        
+        #ATOMS
+        if current1.ObjType == current2.ObjType and current2.ObjType ==2 :
+            if compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Atoms:: Wrong"
+                        return False
+                current2=None
+                continue
+            else:
+                return False
+        
+        
+        #REFERENCE
+        if current1.ObjType == 3 and current2.ObjType == 3 :
+            if compareReference(current1,current2) and compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Reference has something"
+                        return False
+                current2=None
+                continue
+            else:
+                print "compareReference FAILED for "+current1.Name+" "+current2.Name
+                return False
+        
+        
+        #Sets
+        if current1.ObjType == 5 and current2.ObjType == 5:
+            if compareSet(current1,current2)and compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                try:
+                    current1=toProcess1.pop(0)
+                except IndexError:
+                    if len(toProcess2) == 0:
+                        return True
+                    else:
+                        print "Set 2 has something"
+                        return False
+                current2=None
+                continue
+            else:
+                print "compareSet FAILED for "+current1.Name+" "+current2.Name
+                return False
+        
+        if current1.ObjType == 1 and current2.ObjType == 1:
+            if not compareAssoc(current1.PartOfConns,current2.PartOfConns):
+                return False
+        
+        #For FCO's that are connections we need to execute just this "if" block
+        if current1.ObjType == 4 and current2.ObjType == 4:
+            try:
+                current1=toProcess1.pop(0)
+            except IndexError:
+                if len(toProcess2) == 0:
+                    return True
+                else:
+                    print "CONNECTION:: Proc 2 has something"
+                    return False
+            current2=None
+            continue
+        
+        
+        childrenSet1=current1.children()
+        childrenSet2=current2.children()
+        toProcess1.extend(childrenSet1)
+        toProcess2.extend(childrenSet2)
+        
+        if len(childrenSet1)!= len(childrenSet2):
+            print "LENGTH of childrenSet FAILED for " + fco_path(current1)
+            print "\t" + "File 1: " + ", ".join([child.Name for child in current1.children()])
+            print "\t" + "File 2: " + ", ".join([child.Name for child in current2.children()])
+            return False
+        
+        if current1.ObjType == 6 and current2.ObjType == 6:
+            toProcess1.extend(gme.cast(current1).ChildFolders)
+            toProcess2.extend(gme.cast(current2).ChildFolders)
+
+        try:
+            current1=toProcess1.pop(0)
+        except IndexError:
+            if len(toProcess2) == 0:
+                return True
+            else:
+                print "END Proc 2 has something"
+                return False
+        continue
+
+def compareSet(*setFCOs):
+    array=[]
+    for index in range(len(setFCOs)):
+        array.append(dict())
+        array[index][setFCOs[index].Name]=setFCOs[index].AbsPath
+    
+    for index in range(len(setFCOs)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+
+def compareReference(*referenceFCOs):
+    array=[]
+    for index in range(len(referenceFCOs)):
+        array.append(dict())
+        array[index][referenceFCOs[index].Name]=referenceFCOs[index].AbsPath
+    
+    for index in range(len(referenceFCOs)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+   
+def compareAssoc(*current):
+    array=[]
+    for index in range(len(current)):
+        array.append(dict())
+        for point in current[index]:
+            array[index][point.ConnRole]="%s %s" % (point.target.Name,point.target.AbsPath)
+    
+    for index in range(len(current)-1):
+        if(array[index] != array[index+1]):
+            print "Returning False from "+sys._getframe().f_code.co_name
+            return False
+    return True
+
+def compareAttrib(fco1, fco2):
+    def mapAttribs(fco):
+        ret = map(lambda attr: (attr.Meta.Name, attr.Value), fco.Attributes)
+        return dict(ret)
+    fco1Attribs = mapAttribs(fco1)
+    fco2Attribs = mapAttribs(fco2)
+    if fco1Attribs != fco2Attribs:
+        print "'%s' has differing attributes:" % fco1.AbsPath
+        unequalkeys = filter(lambda key: fco1Attribs.get(key) != fco2Attribs.get(key), fco1Attribs.keys())
+        print "\n".join(map(lambda key: "Name: %s: '%s' != '%s' " % (key, fco1Attribs.get(key), fco2Attribs.get(key)), unequalkeys))
+        return False
+    return True
+
+if __name__ == "__main__":
+
+    if(len(sys.argv)==3):
+        file1=sys.argv[1]
+        file2=sys.argv[2]
+        if not os.path.isfile(file1):
+            print False
+        os.path.isfile(file2)
+        if(compare(file1,file2)):
+            print "'%s','%s' are the same" % (file1, file2)
+        else:
+            print "'%s','%s' are not the same" % (file1, file2)
+        gc.collect()
+    else:
+        print "Need exactly two arguments"
\ No newline at end of file

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test.py (from r1070, trunk/Tests/GPyUnit/GME-310/test.py)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test.py	Wed Nov 10 15:18:47 2010	(r1077, copy of r1070, trunk/Tests/GPyUnit/GME-310/test.py)
@@ -0,0 +1,56 @@
+# tests for GME-310
+
+import sys
+import os.path
+import unittest
+import win32com.client
+
+class TestFolderCopy(unittest.TestCase):
+    def __init__(self, input_file, folder_to_copy, destination_folder, name=None):
+        unittest.TestCase.__init__(self, 'test')
+        self.input_file = input_file
+        self.folder_to_copy = folder_to_copy
+        self.destination_folder = destination_folder
+        name = name if name else os.path.splitext(self.input_file)[0]
+        self.output_file = name + "-output.mga"
+        self.correct_file = name + "-correct.mga"
+
+    def test(self):
+        '''
+        Regression test: given self.input_file, move self.folder_to_copy to self.destination_folder. Then check self.output_file against self.correct_file
+        '''
+        # This script depends on late binding. win32com.client.dynamic.Dispatch forces late binding when creating an object,
+        # but early-bound objects may be returned from function calls. Disable late binding completely.
+        import win32com.client.gencache
+        _savedGetClassForCLSID = win32com.client.gencache.GetClassForCLSID
+        win32com.client.gencache.GetClassForCLSID = lambda x: None
+
+        self.project = win32com.client.DispatchEx("Mga.MgaProject")
+        self.project.Open("MGA=" + self.input_file)
+        self.territory = self.project.BeginTransactionInNewTerr()
+
+        modelb = self.project.ObjectByPath(self.folder_to_copy)
+        modelb.Name
+        tomove = win32com.client.DispatchEx("Mga.MgaFolders")
+        tomove.Append(modelb)
+        #self.project.ObjectByPath(self.destination_folder).CopyFolders(tomove, None)
+        self.project.RootFolder.CopyFolders(tomove, None)
+
+        self.project.CommitTransaction()
+        self.project.Save("MGA=" + self.output_file)
+        self.territory.Destroy()
+
+        win32com.client.gencache.GetClassForCLSID = _savedGetClassForCLSID
+        import mgadiff
+        if not mgadiff.compare(self.correct_file, self.output_file):
+            self.fail("Reference file '%s' does not match output '%s'" % (self.correct_file, self.output_file))
+        #print "Reference file '%s' matches output '%s'" % (self.correct_file, self.output_file)
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(TestFolderCopy(input_file="test1.mga", folder_to_copy="/Test1", destination_folder=""))
+    return suite
+
+if __name__ == "__main__":
+    runner = unittest.TextTestRunner()
+    runner.run(suite())

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test1-correct.mga (from r1070, trunk/Tests/GPyUnit/GME-310/test1-correct.mga)
==============================================================================
Binary file (source and/or target). No diff available.

Copied: branches/ServiceReleases_for_10.8.18/Tests/GPyUnit/GME-310/test1.mga (from r1070, trunk/Tests/GPyUnit/GME-310/test1.mga)
==============================================================================
Binary file (source and/or target). No diff available.


More information about the gme-commit mailing list