Author Topic: Collections, Containers, Composites & Nests  (Read 7698 times)

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #30 on: September 29, 2005, 05:53:03 pm »
Paolo;

I'm getting fuzzy again. :(
Quote
The Association Class embodies the link...  Think of the Class as having (at least) two Attributes which correspond to the ends and reference the end Classes.  Each end Class has a collection to reference the set of AssociationClasses that point back to it (and on to the other end).  This is because the if the AssociationClass contains real attributes (whose values correspond to the values appropriate to the link instance in question) they have to go in one place, not in both classes.  So... If the AssociationClass object is nested in one superior, it isn't in the other (and what's more can't be reached by the other).

I built this model:


Generating the code I got:
Code: [Select]

public class BreadProduct {


public BreadDough MadeFrom;

public BreadProduct(){

}


public void finalize() throws Throwable {

}

}
public class BreadDough {


public BreadProduct MadeInTo;

public BreadDough(){

}


public void finalize() throws Throwable {

}
}

public class DoughFormulation {


private int BreadType;

private int Yeald;


public DoughFormulation(){

}


public void finalize() throws Throwable {

}
}


I didn't think I should take you literally and I didn't know what to expect from EA's code generator, but I was hoping for more in the generated code to tie DoughFormulation in a bit more tightly to the other classes.

As you can see, what I got was standard association attributes references in BreadDough and BreadProduct and a DoughFormulation class dangling out in space by itself.  Visibility of DoughFormulation does not seem be an issue is link navigatability.  So are you suggesting that I must add in the missing code to set up the logic in your statement?  ???

Note that I took the link name from our earlier diagrams and decomposed them into role names.  This helped to generate more meaningfull attribute names for the association ends.  Do you have any problems with this notation style instead of using the roles in the link name?
Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #31 on: September 30, 2005, 05:49:20 am »
Quote
Paolo;
I'm getting fuzzy again. :(
[size=13][SNIP][/size]
I didn't think I should take you literally and I didn't know what to expect from EA's code generator, but I was hoping for more in the generated code to tie DoughFormulation in a bit more tightly to the other classes.
Yes, you should have taken me literally (I'm a very literal person... ;D.)  And yes, you should have expected more from the code generator.  However, to give Sparx their due, they appear to be like most OO programmers - they wouldn't know what to do with an AssociationClass if it bit them in the proverbial.

In trying to formulate an answer for you, I tried a few PITS tests today (Programmer-In-The-Street :))  Universally, they either had 1) never seen an AssociationClass or 2) Didn't know what it meant (exactly) and 3) had never created or used one...
Quote
As you can see, what I got was standard association attributes references in BreadDough and BreadProduct and a DoughFormulation class dangling out in space by itself.  Visibility of DoughFormulation does not seem be an issue is link navigability.  So are you suggesting that I must add in the missing code to set up the logic in your statement?  ???
For the present, Yes...

Quote
Note that I took the link name from our earlier diagrams and decomposed them into role names.  This helped to generate more meaningful attribute names for the association ends.  Do you have any problems with this notation style instead of using the roles in the link name?
The names are not correct as they aren't actually role names.  (Actually, the whole model is suspect from a domain point of view, but that isn't the point here...)

Below is the required code for C# to create and manage this relationship.

First the Class definitions...   [Note for simplicity's sake, I've made all the attributes public.]

public class BreadProduct
{
   public ArrayList _DoughFormulations = new ArrayList();    //because the Association is optional manifold                        
   public int Value;    //Just to show we got here...
   public BreadProduct()
   {
   }        

   public void AddDoughFormulation(DoughFormulation associatedDoughFormulation)
   {
       _DoughFormulations.Add(associatedDoughFormulation);
   }
}

public class BreadDough
{
   public ArrayList _DoughFormulations = new ArrayList();    //because the Association is optional manifold                
   public int Value;    //Just to show we got here...

   public BreadDough()
   {
   }        

   public void AddDoughFormulation(DoughFormulation associatedDoughFormulation)
   {
       _DoughFormulations.Add(associatedDoughFormulation);
   }
}

public class DoughFormulation
{
   public BreadDough _BreadDough;
   public BreadProduct _BreadProduct;

   private DoughFormulation()
   {
   }    

   public DoughFormulation(BreadProduct BreadProduct, BreadDough BreadDough, int BreadType, int Yield)
   {
       _BreadProduct = BreadProduct;    //set reference to AssociationEnd
       _BreadDough = BreadDough;    //set reference to AssociationEnd

       _BreadType = BreadType;        //set AssociationClass Attribute    
       _Yield = Yield;        //set AssociationClass Attribute
       
       _BreadProduct.AddDoughFormulation(this);    //Inject reference to AssociationClass
       _BreadDough.AddDoughFormulation(this);    //Inject reference to AssociationClass    
   }
   public int _BreadType;    
   public int _Yield;
}


It should gladden your heart to see some Slot Injections in the AssociationClass constructor...  8)

Next, the code to test and verify the structures...

   BreadProduct oBreadProduct = new BreadProduct();
   oBreadProduct.Value = 23;
   BreadDough oBreadDough = new BreadDough();
   oBreadDough.Value = 77;

   DoughFormulation oDoughFormulation = new DoughFormulation(oBreadProduct, oBreadDough, 1, 5);
   oDoughFormulation = new DoughFormulation(oBreadProduct, oBreadDough, 2, 7);

   System.Collections.IEnumerator oIterator = oBreadProduct._DoughFormulations.GetEnumerator();
   while ( oIterator.MoveNext() )
   {
       DoughFormulation oIteratedDoughFormulation = (DoughFormulation)oIterator.Current;
       Trace.WriteLine(oIteratedDoughFormulation._BreadType + "->" +  oIteratedDoughFormulation._BreadDough.Value);
   }

   oIterator = oBreadDough._DoughFormulations.GetEnumerator();
   while ( oIterator.MoveNext() )
   {
       DoughFormulation oIteratedDoughFormulation = (DoughFormulation)oIterator.Current;
       Trace.WriteLine(oIteratedDoughFormulation._BreadType + "->" +  oIteratedDoughFormulation._BreadProduct.Value);
   }


See how we use the DoughFormulation to traverse to the BreadDough (from the BreadProduct) - and vice versa!

Lastly, the output...

1->77
2->77
1->23
2->23

So it did work!

In C++, the Classes would look like...
Code: [Select]
[size=13]
class DoughFormulation;

class BreadProduct
{
public:
       std::vector<DoughFormulation*> _doughFormulations;
       int Value;
};

class BreadDough
{
public:
       std::vector<DoughFormulation*> _doughFormulations;
       int Value;
};

class DoughFormulation
{
public:
       BreadProduct& _BreadProduct;
       BreadDough& _BreadDough;
       int _BreadType;
       int _Yield;
};
[/size]


Does that help remove the fuzziness?

You should now be able to generate the Java equivalent...

(Now you know why I'm going to emit the code not EA... ;D)

Paolo
« Last Edit: September 30, 2005, 06:56:19 pm by PaoloFCantoni »
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #32 on: September 30, 2005, 06:54:24 am »
Jim,

here is the next iteration of the model.

It's in three diagrams - 'Cos it gets complicated...

BreadProducts can be in a number of forms - here we show two Loaf and Roll.  The {(Form)} is my notation for a GeneralizationSet (until EA supports them properly!).
A BreadProduct can be portioned in a number of ways.  The whole form, cut into slices or broken into pieces.  {(Portioning)}
The slices and pieces are thus «portionOf» meronymies.
An arbitrary set of slices can be reassembled into a cut form (similarly with a set of pieces).

A BreadProduct is made by a process called BreadMaking that is specified by a recipe.  The recipe includes details of making the dough, proving it, and then baking it.  Only whole products can be proved and baked.
Each part of the BreadMaking is a «processOf» meronymy.
Each whole BreadProduct is a «memberOf» the collection of forms on the tray while proving and baking.
Each BreadBakingTray is a «memberOf» the collection of Trays in the batch while baking.
The Oven is comprised of two types of parts the Doors and HeatSources - they're in the «partOf» meronymy.
The Bakery consists of an ingredient StorageRoom, 3 MixingRooms, 2 BakingRooms and a Shop.
The rooms are thus in the «locationOf» meronymy.
Mixing and Proving take place in the MixingRoom, Baking in the BakingRoom, presumably when they've cooled, the BreadProducts end up in the Shop...

BreadDough is made to a recipe which depends on the BreadType.  The BreadType determines the ratio of ingredients.
BreadDouchFormulation determine how much of the ingredients are required to make up a specific mass of dough.
The actual BreadDough reflects the actual amounts of the ingredients used and the actual mass prepared.
In all these cases the relationships to the Ingredient types are «substanceOf» meronymies.

That's ALL the six meronymies!  What a neat example!

Comments?

Paolo



« Last Edit: September 30, 2005, 06:54:49 am by PaoloFCantoni »
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #33 on: September 30, 2005, 10:09:32 am »
Paolo;

Quote
here is the next iteration of the model.
I think it should be the last iteration.  ;D It is a master piece (given that it is a study of the 6 meronyms and not of the bread domain issues).  It stands alone as a complete model.  This, along with the previous iterations, combine to form a wonderful learning experience in the development of a model diagram too!

My Congratulations!  Well done!



How did you get that N-ary icon into the upper right corner of the associationclass elements?



Now that we have arrived at this point, was all of this meronymy 'stuff' just an academic side-track or can we do something with it?   Personally, I think there is much we can do with this.  I would suggest the following areas for further investigation.
  • Earlier in this thread thoughts were presented on the natures of Nest, Container, Collection, and composite.  I've been refactoring those comments into the individual meronymy Stereotypes and I'd like to continue that process and seek comments from the forum
  • I think that the meronymy stereotypes can communicate, to programmers, policy on the nature of how to implement that type of association in code.  I'd like to develop that concept more.
  • I think we can have some interesting discussion on issues raised in this model's domain.  For example:  when a WholeLoaf is sliced, is it morphed into a new type CutLoaf, or are sliced and unsliced states of the WholeLoaf?  And, what are the implementation issues that surround these alternatives? There are other interesting issues raised in this domain too.
  • We need to finish our discussion on the concept of Ownership so that it too is fully refactored.
  • And I think we need to return to the central topic of this thread. :) Is there a collective name we can apply to the concepts of Nest, Container, Collection, and composite?   Now that we've factored out of this collective the issues of merontmys and ownership, what do we have to say about these concepts?  Can we expand on the nature of the containers that might contain these meronymys?
  • And for those who enjoy the academic side of things, we could put this model into the Decorator Pattern to deal with bread condiments.  8)

I think we have a good forking opportunity here for some of these topics.  :D  I'd suggest individual threads for the lesser known meronymys <<locationOf>>, <<portionOf>>, <<activity of>>, and another for "Ownership defined"...

Thoughts anyone?

Cheers

Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #34 on: September 30, 2005, 04:19:07 pm »
Quote
[size=13][SNIP][/size]

How did you get that N-ary icon into the upper right corner of the AssociationClass elements?

I always visually differentiate AssociationClasses from others.  So I set up a UML stereotype colouring for «association»

The icon cam along for free!

Just part of EA's UI (Unique Interface).  
However, a long time back I did postulate that EA should provide the ability to add one (or preferably a number of) icon(s) for a stereotype.   Maybe this is part of the support.

Paolo

BTW, we still need to as the AggregationKind diamonds...
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #35 on: September 30, 2005, 04:33:04 pm »
Quote
BTW, we still need to as the AggregationKind diamonds...

Yes, but I now refer to them as Ownership Diamonds.  ;D  I figure on dealing with them in a thread on Ownership (assuming we agree to fork)  ;)  It would be interesting to put them on this last diagram.  8)
Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #36 on: September 30, 2005, 04:41:41 pm »
Quote
Yes, but I now refer to them as Ownership Diamonds.  ;D  I figure on dealing with them in a thread on Ownership (assuming we agree to fork)  ;)  It would be interesting to put them on this last diagram.  8)
OK..

But we're agreed, after we've fleshed out the rest of the stuff, we'll come back and finalise the model.

Paolo

BTW: I noticed you've now called the stereotype «activityOf» in stead of «processOf»
could we make it «subactivityOf»?  That way ALL the meronymic stereotypes take the part's view...
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #37 on: September 30, 2005, 04:55:57 pm »
Quote
But we're agreed, after we've fleshed out the rest of the stuff, we'll come back and finalise the model.
Agreed.  In fact we can begin that now if you like.

Quote
BTW: I noticed you've now called the stereotype «activityOf» in stead of «processOf»
could we make it «subactivityOf»?  That way ALL the meronymic stereotypes take the part's view...
Good idea, I agree.
Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #38 on: September 30, 2005, 05:56:12 pm »
Quote
Agreed.  In fact we can begin that now if you like.
Go for it...

As you said a few posts back, the stereotypes should give the programmer some indication of the necessary procedural processing involved.

I'm interested from the point of being able to write code from the highest level of abstraction I can get away with.  So, the sooner I can create some patterns for this stuff, the better.

I'll let you kick off the threads...

Paolo

BTW The AssociationClass stuff might warrant a thread of it's own...  Did you follow that?
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #39 on: September 30, 2005, 06:38:25 pm »
Quote
BTW The AssociationClass stuff might warrant a thread of it's own...  Did you follow that?
If you are referring to my recient concerns about it, yes I follow.  Good Idea.

OK, I'll set up the threads.  I'll need a day or two as I'm working this weekend and I need some time to get things organized.  I also got my teaching assignment for the Spring semester so there is a need to organize my lectures notes too.

I'll be back!

Verbal Use Cases aren't worth the paper they are written upon.

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #40 on: October 01, 2005, 01:23:39 pm »
Paolo
In the BreadBaking Diagram, on BreadRecipe, how did you get {Specification} to appear?
Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #41 on: October 01, 2005, 03:58:48 pm »
Quote
Paolo
In the BreadBaking Diagram, on BreadRecipe, how did you get {Specification} to appear?
Advanced button of the General Tab... :)

Paolo
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #42 on: October 01, 2005, 08:36:20 pm »
Paolo;

Two questions and a thought:

1) Have you looked at the Java code EA generates for the BreadRecipe class?  When I did, BreadRecipe.java contains two definitions for the class; one with the nested classes and a second empty class stub.  ??? Whyizzat?

2) I've not used the {specification} check box before nor can I find any documentation on it.  Nor do I understand the Multiplicity value.  Can you explain what they represent and what impact they might have on code generation?

Thought:  Would you consider using the Stereotype of <<intrinsicPartOf>> on the BreadProduct/BreadDough association line to identify the meronymy type?  I'd stereotype the line, not the DoughMixing class.
Verbal Use Cases aren't worth the paper they are written upon.

Paolo F Cantoni

  • EA Guru
  • *****
  • Posts: 5874
  • Karma: +71/-77
  • Inconsistently correct systems DON'T EXIST!
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #43 on: October 02, 2005, 02:28:43 am »
Quote
Paolo;

Two questions and a thought:

1) Have you looked at the Java code EA generates for the BreadRecipe class?  When I did, BreadRecipe.java contains two definitions for the class; one with the nested classes and a second empty class stub.  ??? Whyizzat?

2) I've not used the {specification} check box before nor can I find any documentation on it.  Nor do I understand the Multiplicity value.  Can you explain what they represent and what impact they might have on code generation?

Thought:  Would you consider using the Stereotype of <<intrinsicPartOf>> on the BreadProduct/BreadDough association line to identify the meronymy type?  I'd stereotype the line, not the DoughMixing class.
Jim,

The "Stub" is the constructor.  This constructor is often (in my view mis-)named the default constructor.

In my view, it should be called the constructor with no parameters.  In the DoughFormulation Class, I make it private to ensure it isn't accidentally invoked.

public class DoughFormulation
{
...
   private DoughFormulation()
   {
   }

   public DoughFormulation(BreadProduct BreadProduct, BreadDough BreadDough, int BreadType, int Yield)
   {
...
   }
...
}


The specification checkbox is documented (tautologically) in the EA help file.  As to what it means to define a Classifier as a Specification...  In the past I've used a stereotype for this purpose, but in EA I'm given a property.  BTW: The EA Help file implies a connector can also be a specification, but there doesn't seem to be any way to set it...

There are two related concepts, Cardinality and Multiplicity.  (I've described Multiplicity as a Cardinality that can be zero... - since, in my view, Cardinality can't be zero).  Anyway, EA has both on its UI (Unique Interface), however, but ONLY emits Multiplicity.

Multiplicity defines how many instances of a Class you expect in your environment.  Thus, if a Class is supposed to be a Singleton, this value should be set to 1.

As to your thought...  Firstly, I think (as we've previously discussed) «partOf» actually requires we consider what parts are intrinsically part of the whole and which aren't. If something is intrinsically part of the whole, then it's multiplicity can't have a lower bound of zero.  Looking at the oven; you can't have an oven without a heat source.  But it could be argued that an oven doesn't need door(s).  If so, then we can set the multiplicity of the association to 0..* instead of 1..*.  For my model, I'm asserting that a bread making oven DOES need a door...

Secondly, given my view that the AssociationClass and the Association are effectively one and the same, applying the stereotype to the Association also conceptually applies it to the AssociationClass and vice versa.

Now, as to your specific question... I don't agree that the link you mention should have that stereotype; however, that's because I now think the model is wrong in this area!

You'll see that in the current model, there is a 1:0..* relationship between the BreadDough and the BreadProduct.  The BreadDough, however, is supposed to to be the entire mass for the batch, not just the Dough for a particular product.  What's missing is shown in the diagram below.

The large mass of dough is portioned to make individual products.
I've altered the relationship to allow more then one batch of dough to be used in the creation of the dough for one product (arguable - or at least determined by the rules of the bakery).
As a consequence, I've moved the proving relationships to the BreadProductDough rather than BreadProduct.  Thus the BreadProductDough represents the bread before baking and the BreadProduct after baking...

HTH,
Paolo
Inconsistently correct systems DON'T EXIST!
... Therefore, aim for consistency; in the expectation of achieving correctness....
-Semantica-
Helsinki Principle Rules!

jeshaw2

  • EA User
  • **
  • Posts: 701
  • Karma: +0/-0
  • I'm a Singleton, what pattern are you?
    • View Profile
Re: Collections, Containers, Composites & Nest
« Reply #44 on: October 02, 2005, 05:43:42 am »
Paolo;

I'm used to seeing constructor methods inside of the class they instantiate, not outside of it.  It looks like they are generating two constructors.  What I'm getting is two classes in the same source file (a no no where I come from because of the problems that creates, but allowed by Java) and both classes have the same name!!  I think c++ allows this type of class specification resumption, but I'm not aware that Java does.
Code: [Select]
package Bread;

public class BreadRecipe {

public class BreadDoughFormulation {

private int wholeBreadMass;
private int kneedingDuration;

public BreadDoughFormulation(){}

public void finalize() throws Throwable {}

}


public class ProvingAndBakingFormulation {

private int bakingTime;
private int provingDuration;
private int ovenTemperature;

public ProvingAndBakingFormulation(){}

public void finalize() throws Throwable {}

}


public BreadRecipe(){}  // The constructor !!


public void finalize() throws Throwable {}

}   // End of BreadRecipe class

/**                                 What is this??!!
* @author Jim Shaw
* @version 1.0
* @created 01-Oct-2005 11:09:05 PM
*/
public class BreadRecipe {   // If this is a constructor it should be in the class above??


public BreadRecipe(){

}

public void finalize() throws Throwable {}

}


Quote
In my view, it should be called the constructor with no parameters.
I agree. Most texts are too patronizing about the instantiation process, especally about what goes on behind the scenes.  However, in your code you have placed the constructor inside of the class, which is where I expect to find it.

Quote
Secondly, given my view that the AssociationClass and the Association are effectively one and the same, applying the stereotype to the Association also conceptually applies it to the AssociationClass and vice versa.

 Another unique EA interface then as EA allows them both to be independently Stereotyped.  These extentions to UML might be nice, but they are really confusing if Sparks does not document them as such.  ::)

Quote
If something is intrinsically part of the whole, then it's multiplicity can't have a lower bound of zero.
 A subulty I missed, this is good.

Quote
The large mass of dough is portioned to make individual products.
I've altered the relationship to allow more then one batch of dough to be used in the creation of the dough for one product (arguable - or at least determined by the rules of the bakery).
As a consequence, I've moved the proving relationships to the BreadProductDough rather than BreadProduct.  Thus the BreadProductDough represents the bread before baking and the BreadProduct after baking...
For the sake of consistancy in our goal to demonstrate the six meronymys, can we put one on this association too?
Can you republish the origiional diagram (used in the reply #32 of this thread) so that that reply will always contain the current version?  It would be nice to keep the current drawing published in one place for reference from the other threads forked from here.



Verbal Use Cases aren't worth the paper they are written upon.